2013-03-21 60 views
6

我最近在Java上进行了一次考试,关于Java中通配符泛型的内容很广泛。然而,在实践中对他们的使用很少有人说。我们应该何时使用它们?让我们来看一个典型的用法:Java中通配符泛型的实际用法

void check(Collection<? extends Animal> list) { 
    // Do something 
} 

该文档说,这个集合不允许添加任何元素到列表中。所以基本上可以使用通配符使集合成为只读。这是他们唯一的用法吗?这有什么实际需要吗?在过去的四年中,我参与了很多Java编程项目,但是我还没有看到任何可以广泛使用通配符这样的功能的项目。

因此,从实际的角度来看,有没有什么情况下通配符的泛型是不可避免的和必要的?

+0

基础上的矛盾的答案,你的问题是相当不错的。 :-) – 2013-03-21 06:56:00

回答

3

那么从实际的角度来看,有没有什么情况下 通配符的泛型是不可避免的和必要的?

我不认为它们是'不可避免的和必要的',因为Java编译器无论如何都会擦除它们。但是,在使用它们时,您可以在编译期间获得更紧密的类型检查,避免类型转换。谁又想打字?:)

Guidelines for Wildcard Use

Type Erasure

+0

谢谢,我有点错过了这个指南,它解释了wildard使用的基本规则 – 2013-03-21 07:24:15

1
void check(Collection<? extends Animal> list) { 
    list.add(new Animal()); // compile time error 
    list.add(new Dog()); // compile time error. Dog is subclass of Animal class. 
} 

Java有开发此类仿制药,因为被设置为禁止programmar代码任何他们希望,否则,如果它被允许再后来,他们会发现在运行时环境一团糟。

有时在编程中,您会得到一个方案,您的方法check不会在列表中添加元素,但想要读取这些元素。

您只能添加null值。

+0

你是对的,但请引用一个文件。这听起来很奇怪 – 2013-03-21 07:04:19

0

简而言之,你所说的是错误的。

它与“使集合为只读”无关。

我们仍然可以将元素添加到输入列表中,因为Collection确实声明了add(E)方法。

通配符是直截了当我认为:您实际上想限制输入类型,因为您的逻辑对于某些类型是合理的。

对于你的榜样,您的支票可能使用动物

void check(Collection<? extends Animal> list) { 
    // Do something 
    for (Animal a : list) { 
    a.checkAge(); // checkAge() is method of Animal 
    } 
} 

的一些方法,无需? extends Animal,上面的代码将无法正常工作,因为进入的列表可以是任何东西(不是动物)集合。

因此,我们要确保传入收集集合或集合等,以便我们的代码实际上是有意义的,因为我们从列表中检索元素并将元素视为动物。