代码之家  ›  专栏  ›  技术社区  ›  Sandro

将extends与Java泛型结合使用

  •  2
  • Sandro  · 技术社区  · 15 年前

    假设我有以下代码:

    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();
    }
    

    但是我得到了一个错误,一个是物体,不是动物。如果我尝试使用其他方法,也会发生同样的情况。你知道为什么吗?这和 List<String> List<Object> 泛型教程中的想法?

    谢谢你

    4 回复  |  直到 15 年前
        1
  •  4
  •   Bozho    15 年前

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

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

    Date

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

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

        2
  •  2
  •   polygenelubricants    15 年前

    shelter 使用原始类型的步骤如下:

    Shelter shelter = new Shelter();
    

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

    然后你就可以使用泛型特性了。

    另请参见

    • 有效Java第2版 : 第23条:不要在新代码中使用原始类型 .

      如果您使用原始类型,您将失去泛型的所有安全性和表达性优势。

    • JLS 4.8 Raw Types

      只允许使用原始类型作为对遗留代码兼容性的让步。强烈反对在Java编程语言中引入泛型之后编写的代码中使用原始类型。


    List<String> 不是一个 List<Object>

    是的,Java泛型两者都不是 covariant nor contravariant

    另外,与你的题目所说的不同,我不认为这与 extends

        3
  •  1
  •   Yishai    15 年前

    我认为你的问题的核心在于:

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

    怎么样 shelter 定义?

        4
  •  0
  •   John Feminella    15 年前

    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 = ...