我试图了解Java编译器的想法(我知道,不好主意)......
考虑这个程序:
import java.util.Optional;
public class xx {
public static class Foo<T> {
public interface Bar<T> {
int getX();
}
public Optional<Bar<T>> getBar() {
return Optional.empty();
}
}
public static void main(String[] args) throws Exception {
Foo foo = new Foo(); // note raw type
foo.getBar().get().getX();
}
}
java 1.8.0_112编译器给出:
xx.java:15: error: cannot find symbol
foo.getBar().get().getX();
^
symbol: method getX()
location: class Object
1 error
问题是:在给定Foo
的原始类型foo
的情况下,为什么编译器没有意识到foo.getBar()
的返回类型是Optional<? extends Bar>
而是它显然认为是什么,Optional<?>
?
注意:我知道如何更改此程序以使其编译,这不是问题。
答案 0 :(得分:1)
将原始类型与类型推断结合使用后,将应用JLS 18.5.2中的以下内容
如果在第18.5.1节中约束集减少期间该方法必须进行未经检查的转换,则返回类型和m的调用类型的抛出类型由返回的擦除给出类型和抛出类型的m类型。
由此可见,foo.getBar()
的返回类型确实只是Optional
,所有类型参数都被删除。
解决方案:始终避免原始类型。