Technicznie rzecz biorąc, Java korzysta z wnioskowania typu podczas korzystania z generycznych. Za pomocą ogólnej metody, takiej jak
public <T> T foo(T t) {
return t;
}
Kompilator przeanalizuje i zrozumie to podczas pisania
// String
foo("bar");
// Integer
foo(new Integer(42));
Ciąg znaków zostanie zwrócony dla pierwszego wywołania, a liczba całkowita dla drugiego wywołania na podstawie tego, co podano jako argument. W rezultacie otrzymasz odpowiednie sprawdzanie czasu kompilacji. Ponadto w Javie 7 można uzyskać dodatkowe wnioskowanie o typach podczas tworzenia instancji podobnych
Map<String, String> foo = new HashMap<>();
Java jest na tyle uprzejma, aby wypełnić dla nas puste nawiasy kątowe. Dlaczego Java nie obsługuje wnioskowania o typach w ramach przypisywania zmiennych? W pewnym momencie istniało RFE do wnioskowania typu w deklaracjach zmiennych, ale zostało to zamknięte jako „Nie naprawi”, ponieważ
Ludzie korzystają z nadmiarowości deklaracji typu na dwa sposoby. Po pierwsze, nadmiarowy typ służy jako cenna dokumentacja - czytelnicy nie muszą szukać deklaracji getMap (), aby dowiedzieć się, jaki typ zwraca. Po drugie, nadmiarowość pozwala programiście zadeklarować zamierzony typ, a tym samym skorzystać z kontroli krzyżowej przeprowadzanej przez kompilator.
Współautor, który to zamknął, zauważył również, że jest to po prostu „nie-java-podobne”, z którym jestem jednym z nich się zgodzić. Szczegółowość Javy może być zarówno błogosławieństwem, jak i przekleństwem, ale sprawia, że język jest tym, czym jest.
Oczywiście ten konkretny RFE nie był końcem tej rozmowy. W Javie 7 ponownie rozważono tę funkcję , tworząc niektóre implementacje testowe, w tym jedną przez Jamesa Goslinga. Ponownie ta funkcja została ostatecznie zestrzelona.
Wraz z wydaniem Java 8 możemy teraz wnioskować o typie jako część lambd jako takich:
List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));
Kompilator Java może patrzeć sposobu Collections#sort(List<T>, Comparator<? super T>)
i interfejsu Comparator#compare(T o1, T o2)
i określenia, first
oraz second
powinno być String
w ten sposób pozwalając na programator zrezygnować konieczności przekształca typu w wyrażeniu lambda.