SomeClass和SomeClass之间的区别<! - ? - >

时间:2013-05-16 05:53:03

标签: java generics java-7

在Java 6中,MyClassMyClass<?>之类的内容被认为是相同的,但在Java 7中则不然。

使用Java 7,作为一个例子,我偶然遇到问题,例如Hamcrest匹配器给出了MyClass的实例和期望匹配MyClass<?>的匹配器,并且他们得到编译错误说< / p>

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)

为什么要改变? rawtype和具有未指定类型参数的泛型类型之间有什么区别?

建议的答案并没有真正解释我在这里想到的。其中一条评论说“使用未绑定的通配符(例如在方法签名中)表示有问题的方法知道泛型并承诺该对象的泛型类型。”在这里,我觉得如果它只是一个“信号”,它不应该在编译时引起问题。

我认为MyClass<?>只是MyClass,其中包含有关其内容或操作内容的信息,但是<?>时,没有添加信息,因此它们应该被认为是平等的?

3 个答案:

答案 0 :(得分:3)

这似乎与Java 7中修复的compiler bug有关。

您现在收到的编译器错误是正确的。看起来您正在使用通配符泛型类型调用该方法,例如MyClass<?>Matcher<MyClass<?>>。请注意,通配符类型参数表示“某些未知类型”,因此这些参数可能真的是MyClass<String>Matcher<MyClass<Integer>>,这显然是不正确的。

使用原始类型,例如普通MyClass 选择泛型类型检查,这就是原始类型调用将编译的原因(但可能在运行时失败ClassCastException)。

答案 1 :(得分:1)

修改

Java 6中的

MyClassMyClass<?>不相同,

请参阅此link

为了向后兼容,允许将参数化类型分配给其原始类型:

MyClass<String> stringBox = new MyClass<>();
MyClass rawBox = stringBox;               // OK

但是如果将原始类型分配给参数化类型,则会收到警告:

  MyClass rawBox = new MyClass();

  // rawBox is a raw type of MyClass<T>


  MyClass<Integer> intBox = rawBox;    

// warning: unchecked> conversion

MyClass不是Generic类型,MyClass<?>是泛型类,这意味着MyClass包含另一个类的类型,

例如,它在Java中很常见,我们喜欢这个

List<String> listofString = new ArrayList<String>();

这里它意味着变量listofString是List的一个对象,它将内容限制为只有String类型的对象。 <String>告诉通用。

答案 2 :(得分:1)

正如Jon Skeet所说,他们被认为不平等,我认为这是不正确的。如果我尝试使用Java 6和Java 7,我看不出有任何区别 - 您是如何尝试的?

要了解raw-generics和generics-type之间的区别,请查看此帖子(向下滚动到“如何将原始类型与用作类型参数不同?”): What is a raw type and why shouldn't we use it?