在Java Generics中使用<! - ? - >的“好”理由是什么?

时间:2012-02-19 13:21:59

标签: java generics idioms

我的代码中偶尔会发现我可以通过使用裸通用类或使用通配符来解决问题。

我有一个类似这样的类的设计:

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

一般来说,使我的代码更清晰,而不是没有泛型。

然而,有时我会使用

World theWorld;

或有时我最终会

World<?, ?> theWorld;

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

它对我来说看起来很丑陋和臭,但我不能证明我需要引入以避免它的额外复杂性。

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

3 个答案:

答案 0 :(得分:4)

在Generics教程的Wildcards部分中有一个使用<?>的好例子(用例)。

排序摘要:如果您想编写一个接受各种printCollection的{​​{1}}方法,可以使用Collection作为参数类型。您不能将Collection<?>用作此参数类型,因为它不是所有类型集合的超类型。

在这种情况下,使用Collection<Object>代替“纯”Collection<?>会更安全,因为您无法在Collection方法中将项目添加到Collection<?>(null除外)。 / p>

答案 1 :(得分:3)

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

在其他情况下可能需要这种类型。例如。如果你有Set只存储任何东西,比如缓存,你根本就不关心元素的类型。在其他时候,当您处理特定元素时。

如果您使用过于宽松的绑定类型参数(如<?>非常松散),它会闻起来,但尝试确定之后的类型,例如:使用instanceof或某些自定义类型鉴别器。然后设计的东西很差。

答案 2 :(得分:1)

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

例如:

Collection<? extends Shape> myShapes

此Collection现在可以保留所有对象,它们是Shape的子类。 因此,在添加作为Shape子类的任何对象时,您是类型安全的。例如:

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