在 Java 6 中类似 MyClass
和MyClass<?>
被认为是平等的,但在 Java 7 中它们并非如此。
以 Java 7 为例,我偶然发现了 Hamcrest 匹配器的问题,这些匹配器给出了 MyClass
的实例。和一个期望匹配 MyClass<?>
的匹配器,他们得到编译错误说
no suitable method found for assertThat(MyClass,Matcher<MyClass<?>>)
[ERROR] method Assert.<T#1>assertThat(T#1,Matcher<? super T#1>) is not applicable
[ERROR] (actual argument Matcher<MyClass<?>> cannot be converted to Matcher<? super MyClass> by method invocation conversion)
为什么要改变?原始类型和具有未指定类型参数的泛型类型之间有什么区别?
建议的答案并没有真正解释我在这里想知道的内容。其中一条评论说“使用未绑定(bind)的通配符(例如在方法签名中)标志着一个 promise ,即所讨论的方法知道泛型并将尊重该对象的泛型类型。”在这里,我再次认为,如果它只是一个“信号”,那么它不应该在编译时引起问题。
我觉得MyClass<?>
只是 MyClass
包含有关其包含或操作内容的信息,但虽然它是 <?>
,没有添加信息,所以它们应该被认为是相等的?
最佳答案
这似乎与 compiler bug 有关Java 7 中已修复该问题。
您现在收到的编译器错误是正确的。看起来您正在使用通配符泛型类型调用该方法,例如MyClass<?>
和Matcher<MyClass<?>>
。请注意,通配符类型参数意味着“某种未知类型”,因此这些参数实际上可能是 MyClass<String>
和Matcher<MyClass<Integer>>
,这显然是不正确的。
使用原始类型,例如普通MyClass
选择退出泛型类型检查,这就是为什么使用原始类型的调用会编译(但可能在运行时失败,并出现 ClassCastException
)。
关于java - SomeClass 和 SomeClass<?> 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16579891/