使用Java泛型扩展

时间:2010-04-18 13:10:55

标签: java generics

让我们说我有以下代码:

public class Shelter<A extends Animal, B extends Animal>
{
     List<A> topFloor = new Vector<A>();
     List<B> bottomFloor = new Vector<B>();

     public A getFirstTopFloorAnimal(){return topFloor.get(0);}
     public B getFirstBottomFloorAnimal(){return bottomFloor.get(0);}

     //These 3 methods compile but when I try to use it, they all only return objects
     public List<Animal> getAnimals()
     { 
         List<Animal> a = new Vector<Animal>(topFloor); 
         a.addAll(bottomFloor); 
         return a;
     }

     public List<A> getTopFloor(){return topFloor;}
     public List<B> getBottomFloor(){return bottomFloor;}
}
然后我尝试做以下事情:

for(Animal a : shelter.getTopFloor()){
    a.growl();
}

但是我编译错误,我得到的错误是A是一个对象,而不是动物。如果我尝试使用其他方法,也会发生同样的情况。任何想法为什么会这样?这与List<String>是否与Generics教程中的List<Object>想法有关吗?

谢谢

4 个答案:

答案 0 :(得分:4)

泛型只是一个编译时的概念,以提高类型安全性。

您不能使用它们来过滤在运行时添加到集合的值。您必须手动进行过滤(例如,使用instanceOf

例如,这可以使用,并允许您添加Date

List<String> list = new ArrayList<String>();
((List) list).add(new Date());

因此,在添加元素时,您(我们尚未看到的)问题的解决方案是不使用原始类型。

答案 1 :(得分:2)

我最好的猜测是你已声明shelter使用原始类型,如下所示:

Shelter shelter = new Shelter();

你真的应该做到以下几点:

Shelter<Cat,Dog> shelter = new Shelter<Cat,Dog>();

然后你实际上使用了泛型功能。

另见

  • Effective Java 2nd Edition 第23项:不要在新代码中使用原始类型

      

    如果使用原始类型,则会失去仿制药的所有安全性和表现力。

  • JLS 4.8 Raw Types

      

    原始类型的使用仅允许作为遗留代码兼容性的让步。强烈建议不要在将通用性引入Java编程语言之后编写的代码中使用原始类型。 未来版本的Java编程语言可能会禁止使用原始类型。


  

List<String>不是List<Object>

是的,Java泛型既不是covariant nor contravariant。如果你试图将一个泛型类型转换为另一个类型,这只是一个问题,这似乎不是你想要做的。

此外,与主题标题所说的不同,我认为这与extends无关,无法在泛型中绑定类型参数。

答案 2 :(得分:1)

我认为问题的核心在于:

for(Animal a : shelter.getTopFloor()){
    a.growl();
}

如何定义shelter

答案 3 :(得分:0)

这是因为当您将项目放在Vector中时,它们会作为对象进入,而不是Animal的实例。

 public List<Animal> getAnimals()
 { 
     Vector a = new Vector(topFloor); // <-- Not generic!
     a.addAll(bottomFloor); 
     return a;                        // <-- Returning non-generic Vector.
 }

请改为尝试:

 Vector<Animal> a = ...