Java泛型中的问号

Sam*_*uel 5 java generics wildcard set

我读过<?>的内容与完全相同<? extends Object>。那有什么区别:

  1. Set<?>
  2. Set<Object>
  3. Set

我尝试将String.class和添加MyClass.class到所有这些集合中,但是在第二种情况下,它无法编译。

我没有得到的另一个例子是:

  1. Set<Class>
  2. Set<Class<?>>

在我看来,它们是相同的,但是如果我有一个可以返回的方法Set<Class<?>>,则无法将其返回值分配给type变量Set<Class>

很抱歉,如果这是重复的,但是我已经阅读了所有其他文章,并且示例很少,但我仍然不明白。

Ram*_*lfc 5

使用Set<?>,我可以使用我想要的任何类型,例如 :Set<?> s =new HashSet<Intger>()Set<?> s =new HashSet<String>().Since,我?可以引用任何我不允许放入null集合中以外的任何内容,并且我将Object退出集合。

Set<Object>说我只能Object为 ex分配类型:Set<Object> s =new HashSet<Object>()但不能Set<Object> s =new HashSet<String>()。在这种情况下,我可以添加任何类型,因为Object是超级基本类型,但我会Object退出集合。

Set是基本的原始类型,您可以添加任何内容并从中获取Object类型。

Set<Class>不同于Set<Class<?>>。第一个说“我是一组非特定Class类型”,而第二个说“我是一组特定Class类型但不知道是哪一个”。


Mik*_*kis 0

  1. 使用没有泛型参数的泛型类(例如Setand Class、and ,进而扩展为Set<Class>)是一种不好的做法,应不惜一切代价避免。如果一个类是泛型的,则始终使用其泛型形式。如果您的 IDE/编译器在您尝试使用它们时没有给您很大的警告,那么您没有启用足够的警告。

                                      Austin Powers - 我注意到你忽略了编译器警告; 我也喜欢危险的生活。

  1. 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"
Run Code Online (Sandbox Code Playgroud)