Oracle Java SE 8u20 JDK中泛型静态方法调用的Java泛型不兼容类型编译错误

Oracle Java SE 8u20 JDK中泛型静态方法调用的Java泛型不兼容类型编译错误,java,generics,compilation,type-erasure,incompatibletypeerror,Java,Generics,Compilation,Type Erasure,Incompatibletypeerror,使用Oracle Java SE 8u20 JDK编译下面的代码时,前三个赋值编译良好(对于工作*变量),但第四个赋值(对于失败1变量)生成以下编译错误: 错误: incompatible types: Set<Set<Object>> cannot be converted to Set<Set<? extends Object>> 不兼容类型:无法将Set转换为Set您在fails1上的键入过于严格,这与声明时对其施加的相对宽松的通配符约束相

使用Oracle Java SE 8u20 JDK编译下面的代码时,前三个赋值编译良好(对于
工作*
变量),但第四个赋值(对于
失败1
变量)生成以下编译错误:

错误:

incompatible types: Set<Set<Object>> cannot be converted to Set<Set<? extends Object>>

不兼容类型:无法将Set转换为Set您在
fails1
上的键入过于严格,这与声明时对其施加的相对宽松的通配符约束相矛盾

格式为<代码>?extends T
表示您愿意接受
T
及其所有子类型。但是,您明确地将右侧限制为
对象

本质上,你是在尝试:

Set<Set<? extends Object>>
这只是一组
对象
类型

对于
工作1
,这种情况不会发生的原因是:它定义了一个
集合
,其中包含
对象
对象
的后代的元素,并且由于
对象
至少满足其中一个要求,在后台进行的操作将满足此规则

同样,这是您正在使用的Java 8—除非Java编译器不能在这里进行类型推断,否则传入这些类型几乎没有任何好处。

除非使用
通配符,否则
之间的任何内容都是类型不变的


SetIt的类型也不会在Java 7上编译。请记住,类型擦除永远不会解决编译错误,例如当前的编译错误。在编译时没有擦除——所有类型信息都在那里。我建议阅读以下问答:@MarkoTopolnik:您链接中的答案给了我解决方案,我将在下面回答。谢谢。我认为最重要的信息应该是顶层的
和嵌套位置的
之间的区别。即,为什么您的解释不适用于
工作1
。从表面上看,还有一个过于严格的右手边。不同的是,顶级的
要接受通配符捕获,而嵌套的则不是。这不是一个坏主意。我会在半小时内完成。我们将尝试以一种令人满意的方式来表达它。
Set<Set<? extends Object>>
Set<Object>
Set<? extends Set<? extends Object>> works4 = Collections.<Set<Object>>emptySet();