Java泛型中的问号

时间:2015-11-30 11:57:04

标签: java generics set wildcard

我读过<?><? extends Object>完全相同。然后有什么区别:

  1. Set<?>
  2. Set<Object>
  3. Set
  4. 我尝试将String.classMyClass.class添加到所有这些集合中,但在第二种情况下它不会编译。

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

    1. Set<Class>
    2. Set<Class<?>>
    3. 对我而言似乎它们是相同的,但如果我有一个返回Set<Class<?>>的方法,我就不能将它的返回值赋给Set<Class>类型的变量。

      如果这是重复的话,我很抱歉,但我已经阅读了所有其他帖子,但很少有例子,我仍然无法理解。

2 个答案:

答案 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)

  1. 使用没有通用参数的通用类(例如SetClass,以及扩展名Set<Class>)是不好的做法,不惜一切代价避免使用。如果类是通用的,请始终使用其通用形式。如果您的IDE /编译器在您尝试使用它们时没有给您大量警告,那么您没有启用足够的警告。
  2. Austin Powers - I noticed you ignore compiler warnings; I too like to live dangerously.

    1. Set<?>是一组几乎任何东西,但明确定义为一组特别没有,所以它实际上是无法使用的。不要这样做。
    2. 所以,你应该从不尝试“将[返回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"