2016-05-16 115 views
7
Set<Object> removedObjs = new HashSet<>(); 
List<? extends MyEntity> delObjs = (List<? extends MyEntity>) new ArrayList<>(removedObjs); 

MyEntity是标记接口。Java 8不兼容类型错误

上面的代码是在工作正常(Java版本“1.7.0_91”,要准确),但不是在(Java版本“1.8.0_77”)

在Java8,我收到以下异常:

incompatible types: ArrayList<Object> cannot be converted to List< ? extends MyEntity>

+4

如果你删除'''''你应该只是一个警告。如果它在Java 8中不起作用,那么它可能不应该在Java 7中工作。 –

+0

它可以在我的环境中编译器在eclipse中只有警告中的JAVA1.8.0_92:类型安全性:未检查从ArrayList转换为List <?扩展MyEntity>但不能javac – andy

+3

看看代码,这似乎是合乎逻辑的,它不应该工作。只需在两行之间插入'removedObjs.add(“42”);来查看原因。 – biziclop

回答

8

的Java 8改变了很多类型推断和相关科目。因此,如果某些边缘案例(如黑幕演员)突然失效,这并不奇怪。

不管是什么原因,你仍然可以施展你的清单,但它是稍微难看比以前:

(List<? extends MyEntity>) (List) new ArrayList<>(removedObjs);

正如彼得Lawrey的评论指出,这可以作为

写更短

(List) new ArrayList<>(removedObjs);

+0

Java语言规范不鼓励使用原始类型,除了处理泛型之前的传统代码。另见http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it – meriton

11

你的代码既不应工作在Java 7中,也没有在Java中8,因为你试图施放一个ArrayList<Object>(从构造函数返回的类型)到List<? extends MyEntity>,即使在编译时也没有意义(见this question)。这就是编译器抱怨的原因。

将下面的代码编译:

Set<Object> removedObjs = new HashSet<>(); 
List<? extends Integer> delObjs = (List) new ArrayList<>(removedObjs); 

不过,既然你执行的是不安全的转换,编译器将抛出一个警告。

编辑:由于@汤姆指出:

应该不是“你的代码不应该在Java 7的工作”,但它的工作,因为编译器检查仍然在那个版本有点故障。 Java 8中已经修复了这个问题,这就是为什么它现在失败了。

+14

*“你的代码不应该在java 7中工作”*它应该'但它工作,因为编译器检查在该版本中仍然有点错误。 Java 8中已经修复了这个问题,这就是为什么它现在失败了。 (只是一个便条) – Tom

+0

^这应该被添加到答案。 –

+0

如果您正在编写代码,请使用反引号('\'')。 – cst1992