Why is Java's type inference so weak?

2020-03-03 09:43发布

问题:

Say, I have a method:

public static <T> Collection<T> addToCollection(T element, Collection<T> collection) {
    collection.add(element);
    return collection;
}

And then when trying to compile this code:

Integer i = 42;
Collection<Integer> result = addToCollection(i, Collections.emptyList());

I get an error Type mismatch: cannot convert from Collection<Object> to Collection<Integer>. Could anyone explain why the type system cannot infer that Collections.emptyList() should be of type Collection<Integer>?

The example above is obviously quite artificial, but I stumble upon that limitation all the time and it's really annoying. After having read Effective Java I have found out that you can simply do Collections.<Integer>emptyList() (must say, that was quite a revelation for me at the time) and have everything compiling smoothly, but when you have some complicated type then it really is a nuisance.

I'm just wondering if this is some sort of bug, or are there any valid reasons for it to work that way?

回答1:

The type inference system has been improved in Java 8, with the introduction of target typing, in order to give more expressivity to streams and lambdas. As a consequence your code compiles with Java 8.

More about it in the updated tutorial, with a very similar example towards the very bottom of the page.



回答2:

Collections.emptyList() returns a List<Object> which is passed through your addToCollection() method. And since Object is not Integer, this fails.



回答3:

Whats harm in doing this?

Integer i = 42;
List<Integer> emptyList = Collections.emptyList();
Collection<Integer> result = addToCollection(i, emptyList);

In java 8 it will be taken care.