这个类在Java 7中编译好,但在Java 8中没编译:
public class Foo {
public static void main(String[] args) throws Exception {
//compiles fine in Java 7 and Java 8:
Class<? extends CharSequence> aClass = true ? String.class : StringBuilder.class;
CharSequence foo = foo(aClass);
//Inlining the variable, compiles in Java 7, but not in Java 8:
CharSequence foo2 = foo(true ? String.class : StringBuilder.class);
}
static <T> T foo(Class<T> clazz) throws Exception {
return clazz.newInstance();
}
}
Run Code Online (Sandbox Code Playgroud)
编译错误:
错误:(9,29)java:类Foo中的方法foo不能应用于给定的类型; required:java.lang.Class发现:true?Str [...]类
原因:推断类型不符合推断的等式约束:java.lang.StringBuilder等式约束:java.lang.StringBuilder,java.lang.String
为什么这在Java 8中停止工作?是故意/某些其他功能的副作用,还是仅仅是编译器错误?
说,我有一个方法:
public static <T> Collection<T> addToCollection(T element, Collection<T> collection) {
collection.add(element);
return collection;
}
Run Code Online (Sandbox Code Playgroud)
然后在尝试编译此代码时:
Integer i = 42;
Collection<Integer> result = addToCollection(i, Collections.emptyList());
Run Code Online (Sandbox Code Playgroud)
我收到一个错误Type mismatch: cannot convert from Collection<Object> to Collection<Integer>.任何人都可以解释为什么类型系统无法推断Collections.emptyList()应该是类型Collection<Integer>?
上面的例子显然是非常人为的,但我一直偶然发现这个限制,这真的很烦人.在阅读了Effective Java之后,我发现你可以简单地做Collections.<Integer>emptyList()(必须说,那对我来说这是一个很好的启示)并且让所有东西都能顺利编译,但是当你有一些复杂的类型时,那真的是令人讨厌的.
我只是想知道这是不是某种错误,还是有任何正当理由让它以这种方式工作?