Thursday, August 27, 2009

Java, который я не понимаю

Еще одна, наряду с добавлением элементов из одной типизированной wildcard коллекцией в другую особенность родовых типов в Java.

А именно, параметры для родовых типов не определяются автоматически (infer) из контекста. Хотя определяются автоматически для родовых функций. Поясню на примере. Фрагмент кода 1:
<T> String cat(T a, T b) { return String.valueOf(a) + String.valueOf(b); } ... System.out.println(cat(1, 2));
В этом фрагменте при инстанциировании cat компилятор автоматически определит, что T - int.

Фрагмент кода 2:
class Cat<T> { T a, b; Cat(T a, T b) { this.a = a; this.b = b; } String cat() { return String.valueOf(a) + String.valueOf(b); } } ... System.out.println(new Cat(1, 2).cat());
В этом фрагменте при инстанциировании класса Cat компилятор выдаст предупреждение, что класс родовой класс используется без указания родового параметра. Хотя из вызова конструктора можно было эти родовые параметры определить. Так как компилятор такого не делает, приходится лишний раз руками указывать тип:
System.out.println(new Cat<Integer>(1, 2).cat());
Это, конечно, плохо с точки зрения читабельности и поддерживаемости кода.

В Internet не очень много информации, почему так сделано. Я нашел только одно старое упоминание вот здесь форуме Sun, в котором говориться о том, что автоматическое определение родовых параметров расходится с идеологией Java. Но для методов так же сделано - почему для них не расходиться.