【问题标题】:What are the 'good' reasons to use <?> in Java Generics?在 Java 泛型中使用 <?> 的“好”理由是什么?
【发布时间】:2012-03-10 02:35:29
【问题描述】:

有时在我的代码中,我发现我可以通过使用裸泛型类或带有通配符的类来解决问题。

我有这样一个类的设计:

Class World<T, C> { .... }

总的来说,我的代码肯定比没有泛型时更干净。

然而,有时我会使用

World theWorld;

或者有时我会得到 ​​p>

World<?, ?> theWorld;

我这样做是因为它似乎是让编译器接受它和我的 试图避免它们导致我更多的铸造或继承复杂性。

对我来说它看起来又丑又臭,但我无法证明我需要引入额外的复杂性来避免它。

在哪些情况下(如果有的话)您认为使用裸泛型或通配符泛型是可接受的 Java 惯用语?

【问题讨论】:

    标签: java generics idioms


    【解决方案1】:

    在泛型教程的Wildcards 部分中有一个很好的使用&lt;?&gt; 的示例(用例)。

    排序总结:如果你想编写一个接受各种CollectionprintCollection 方法,你可以使用Collection&lt;?&gt; 作为参数类型。您不能为此目的使用Collection&lt;Object&gt; 作为参数类型,因为它不是所有类型集合的超类型。

    在这种情况下使用Collection&lt;?&gt; 而不是“纯”Collection 更安全,因为您不能在printCollection 方法中将项目添加到Collection&lt;?&gt;(null 除外)。

    【讨论】:

    • 好吧,我认为这是有道理的......除了我不遵循“你不能为此目的使用 Collection 作为参数类型,因为它不是所有类型的集合的超类型。 "我原以为会是……我原以为你不能这样做的原因是 Collection 与 Collection 完全不同。然而,一个集合 extends Object> 是合乎逻辑的,但这相当于 Collection>。你能确认一下吗?
    • 收藏> 和收藏 extends Object> 几乎相同。有关细微差别,请参阅此答案:stackoverflow.com/a/2016382/122442
    【解决方案2】:

    任何时候您可以使用泛型,但在特定情况下不需要&lt;?&gt; 粗略地告诉编译器:“我知道泛型,但我现在不需要类型”。

    也许在其他情况下需要该类型。例如。如果你有一个 Set 只存储任何东西,比如缓存,而你根本不关心元素的类型。在其他时候,当您处理特定元素时,您会这样做。

    如果你使用过于松散的类型参数(比如&lt;?&gt;,它非常松散),但之后尝试确定类型,例如使用instanceof 或一些自定义类型鉴别器。然后有些东西设计得很糟糕。

    【讨论】:

      【解决方案3】:

      当您想要存储多个对象时,通配符也非常有用,这些对象是另一个类的子类。

      例如:

      Collection<? extends Shape> myShapes
      

      这个集合现在可以保留所有对象,它们是 Shape 的子类。 因此,在添加任何属于 Shape 子类的对象时,您是类型安全的。例如:

      myShapes.add(new Rectangle())
      myShapes.add(new Triangle())
      

      【讨论】:

      • 有趣!我试过“Collection a;”发现这是无效的。所以用“?”而是!
      • T 仅当您在其中实现它的类本身是通用的时才有效,这意味着一旦该类的对象被实例化,VM 就会知道 T。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多