Java Type Systems – Why Java Does Not Use Type Inference

data typesjavaprogramming-languagestype-systems

I have always wondered why Java does not do type inference given that the language is what it is, and its VM is very mature. Google's Go is an example of a language with excellent type inference and it reduces the amount of typing one has to do. Is there any special reason behind this feature not being a part of Java?

Best Answer

Technically speaking, Java does have type inferencing when using generics. With a generic method like

public <T> T foo(T t) {
  return t;
}

The compiler will analyze and understand that when you write

// String
foo("bar");
// Integer
foo(new Integer(42));

A String is going to be returned for the first call and an Integer for the second call based on what was input as an argument. You will get the proper compile-time checking as a result. Additionally, in Java 7, one can get some additional type inferencing when instantiating generics like so

Map<String, String> foo = new HashMap<>();

Java is kind enough to fill in the blank angle brackets for us. Now why doesn't Java support type inferencing as a part of variable assignment? At one point, there was an RFE for type inferencing in variable declarations, but this was closed as "Will not fix" because

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.

The contributor who closed this also noted that it just feels "un-java-like", which I am one to agree with. Java's verbosity can be both a blessing and a curse, but it does make the language what it is.

Of course that particular RFE was not the end of that conversation. During Java 7, this feature was again considered, with some test implementations being created, including one by James Gosling himself. Again, this feature was ultimately shot down.

With the release of Java 8, we now get type inference as a part of lambdas as such:

List<String> names = Arrays.asList("Tom", "Dick", "Harry");
Collections.sort(names, (first, second) -> first.compareTo(second));

The Java compiler is able to look at the method Collections#sort(List<T>, Comparator<? super T>) and then the interface of Comparator#compare(T o1, T o2) and determine that first and second should be a String thus allowing the programmer to forgo having to restate the type in the lambda expression.

Related Topic