我读过<?>
与<? extends Object>
完全相同。然后有什么区别:
Set<?>
Set<Object>
Set
我尝试将String.class
和MyClass.class
添加到所有这些集合中,但在第二种情况下它不会编译。
我没有得到的另一个例子是:
Set<Class>
Set<Class<?>>
对我而言似乎它们是相同的,但如果我有一个返回Set<Class<?>>
的方法,我就不能将它的返回值赋给Set<Class>
类型的变量。
如果这是重复的话,我很抱歉,但我已经阅读了所有其他帖子,但很少有例子,我仍然无法理解。
答案 0 :(得分:1)
使用Set<?>
,我可以使用我想要的任何类型:Set<?> s =new HashSet<Intger>()
或Set<?> s =new HashSet<String>()
。因为,我可以让?
提及任何我不允许的内容将null
以外的任何内容放入集合中,我将从集合中获取Object
。
Set<Object>
说我只能为ex:Object
但不是Set<Object> s =new HashSet<Object>()
分配类型Set<Object> s =new HashSet<String>()
。在这种情况下,我可以添加任何类型,因为Object
是超级基类型,但我将从集合中获得Object
。
Set
是基本的原始类型,您可以添加任何内容并从中获取Object
类型。
Set<Class>
与Set<Class<?>>
不同。第一个说“我是一组非特定Class
类型”,而第二个则说“我是一组特定的{{ {1}}类型但不知道哪个“。
答案 1 :(得分:0)
Set
和Class
,以及扩展名Set<Class>
)是不好的做法,不惜一切代价避免使用。如果类是通用的,请始终使用其通用形式。如果您的IDE /编译器在您尝试使用它们时没有给您大量警告,那么您没有启用足够的警告。Set<?>
是一组几乎任何东西,但明确定义为一组特别没有,所以它实际上是无法使用的。不要这样做。所以,你应该从不尝试“将[返回Set<Class<?>>
]的方法的[返回值]赋给Set<Class>
类型的变量”,因为你应该从不拥有Set<Class>
类型的变量,您应该只有Set<Class<?>>
类型的变量。
更好的是,如果适用于您的情况,请尝试使用Set<Class<? extends MyClass>>
类型的变量。越具体越好。
另外,请注意以下事项:
//invalid (gives errors)
Set<?> foo1 = new HashSet<>();
foo1.add( String.class ); //error: cannot convert to capture<?>
foo1.add( Generics2.class ); //error: cannot convert to capture<?>
//perfectly fine, though lame (don't use `Object`, use something specific)
Set<Object> foo2 = new HashSet<>();
foo2.add( String.class );
foo2.add( Generics2.class );
//invalid (gives warnings, in my opinion it should give errors.)
Set foo3 = new HashSet<>(); //warning "raw use of parameterized class 'foo3'"
foo3.add( String.class ); //warning "unchecked call to member of raw type"
foo3.add( Generics2.class ); //warning "unchecked call to member of raw type"