Tecnicamente falando, Java tem inferência de tipos ao usar genéricos. Com um método genérico como
public <T> T foo(T t) {
return t;
}
O compilador irá analisar e entender que quando você escreve
// String
foo("bar");
// Integer
foo(new Integer(42));
Uma String será retornada para a primeira chamada e um Integer para a segunda chamada com base no que foi inserido como argumento. Você obterá a verificação adequada em tempo de compilação como resultado. Além disso, no Java 7, pode-se obter inferências de tipo adicionais quando instanciar genéricos como assim
Map<String, String> foo = new HashMap<>();
Java tem a gentileza de preencher os colchetes em branco para nós. Agora, por que o Java não suporta a inferência do tipo como parte da atribuição de variáveis? Em um ponto, houve um RFE para inferência de tipo em declarações de variáveis, mas isso foi fechado "Não vai consertar" porque
Humans benefit from the redundancy of the type declaration in two ways. First, the redundant type serves as valuable documentation - readers do not have to search for the declaration of getMap() to find out what type it returns. Second, the redundancy allows the programmer to declare the intended type, and thereby benefit from a cross check performed by the compiler.
O colaborador que fechou isso também notou que ele simplesmente parece "não-java-like", com o qual eu estou de acordo. A verbosidade de Java pode ser tanto uma bênção quanto uma maldição, mas faz da linguagem o que ela é.
É claro que esse RFE em particular não foi o fim dessa conversa. Durante o Java 7, esse recurso foi novamente considerado , com algumas implementações de teste sendo criado, incluindo um pelo próprio James Gosling. Mais uma vez, esse recurso foi finalmente abatido.
Com o lançamento do Java 8, agora obtemos a inferência de tipos como parte dos lambdas:
List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));
O compilador Java pode examinar o método Collections#sort(List<T>, Comparator<? super T>)
e, em seguida, a interface de Comparator#compare(T o1, T o2)
e determine que first
e second
devem ser String
, permitindo que o programador tenha que reafirmar o tipo na expressão lambda.