Tecnicamente parlando, Java ha tipo di inferenza quando si usano i generici. Con un metodo generico come
public <T> T foo(T t) {
return t;
}
Il compilatore analizzerà e capirà che quando scrivi
// String
foo("bar");
// Integer
foo(new Integer(42));
Una stringa verrà restituita per la prima chiamata e un intero per la seconda chiamata in base a ciò che è stato inserito come argomento. Come risultato otterrai il corretto controllo in fase di compilazione. Inoltre, in Java 7, si può ottenere qualche inferenza di tipo aggiuntivo quando istanziazione di generici come tale
Map<String, String> foo = new HashMap<>();
Java è abbastanza gentile da riempire le parentesi angolari vuote per noi. Ora, perché Java non supporta il tipo di inferenza come parte dell'assegnazione delle variabili? A un certo punto, c'era un RFE per l'inferenza del tipo nelle dichiarazioni variabili, ma questo era chiuso come "Non risolverà" perché
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.
Il contributore che ha chiuso questo ha anche notato che si sente semplicemente "un-java-like", con il quale sono d'accordo. La verbosità di Java può essere sia una benedizione che una maledizione, ma rende il linguaggio quello che è.
Ovviamente quella particolare RFE non era la fine di quella conversazione. Durante Java 7, questa funzione era nuovamente considerata , con alcune implementazioni di test in fase di creazione, tra cui uno di James Gosling stesso. Ancora una volta, questa funzione è stata in ultima analisi abbattuta.
Con il rilascio di Java 8, ora otteniamo l'inferenza di tipo come parte di lambda in quanto tale:
List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));
Il compilatore Java è in grado di esaminare il metodo Collections#sort(List<T>, Comparator<? super T>)
e quindi l'interfaccia di Comparator#compare(T o1, T o2)
e determina che first
e second
dovrebbero essere un String
, consentendo così al programmatore di rinunciare a dover rideterminare il tipo nell'espressione lambda.