收藏品的泛型

时间:2013-04-28 05:19:54

标签: java generics collections

问题1: 鉴于:

  List<Object> lo = new ArrayList<Object>();

如果我理解正确,ArrayList<>()中的参数必须为Object,那么我们是否需要编写它?或者我们就这样跳过它:

List<Object> lo = new ArrayList<>();   

问题2: 鉴于:

List<? extends Animal> myArray = new ArrayList<Dog>();  

据我了解,=的左侧表示myArrayList类型的引用,可以是List<Cat>List<Dog>,... .. =的右侧怎么样,这意味着什么?这是否意味着引用myArray被分配给仅包含List的{​​{1}}的真实对象?如果是,我不能不考虑Dog右侧的信息是有用还是必要的情况。你能举个例子吗

=

是必不可少的还是至少有用的?

4 个答案:

答案 0 :(得分:2)

Q1:您可以在Java 7中跳过它。

Q2:此声明没有多大意义。 List<? extends SomeClass>作为方法的参数很有用,以便允许开发人员传递包含扩展SomeClass的所有类型的列表。但是,它禁止在该列表中添加任何内容:

public void addAnimal(List<? extends Animal> animals) {
      animals.add(new Dog()); // Compiler error
}

如果您想实现这一目标,则必须使用超级关键字:List<? super SomeClass>

另见:

答案 1 :(得分:2)

第一个问题:Java 7 introduces the diamond operator,在大多数情况下作为写出完整类型的泛型的语法糖。它可以省略,但它“仍在那里”。

第二个问题:

  • 左侧是upper-bounded generic wildcard的列表。 包含任何扩展或实现名为Animal的类的对象。除非将列表定义为lower-bounded generic wildcard(使用super关键字),否则您将无法在该列表中插入任何值。关于如何使用它们,何时使用它们以及如何对它们进行分类in this Java Trail还有更多内容。

  • 右侧悬挂在那里有点不寻常,但它可用于分配上限泛型类型列表,如果您首先填充您想要的列表

    List<? extends Animal> fooList = new ArrayList<>();
    List<Dog> barList = new ArrayList<>();
    barList.add(new Dog());
    barList.add(new Dog());
    barList.add(new Dog());
    barList.add(new Dog());
    
    fooList = barList;
    

    您仍然需要将其作为上限泛型类型进行迭代:

    for(Animal d : fooList) {
        d.walk();
        d.talk();
    }
    

基本上,你现在拥有它的方式既误导又无用,因为新的ArrayList<Dog>是空的,无法添加。

答案 2 :(得分:1)

  1. 只要您使用的是Java 7,只要引用类型不包含通配符(如List<? extends Number>中所示),就可以这样做。
  2. 使用通配符时,只允许执行类型安全操作。在这种情况下,您可以从列表中读出来。
  3. 例如:

    List<? extends Number> list = ...;
    //more code
    Number n = list.get(0);
    

    但你不能将元素放入列表中:

    List<? extends Number> list = ...;
    //more code
    list.add(new Double(1.5));  //compile-time error
    

    你不能,因为你不知道list的实际类型。如果类型不是Double而是Integer

    ,该怎么办?

答案 3 :(得分:0)

  

是否意味着将引用myArray分配给只包含Dog的List的真实对象?

这意味着myArray被分配到包含Dog或任何类型的狗的列表,这些狗派生自Dog,但是在使用myArray时,只能保证myArray中包含的对象是Animals。请注意,在java中,类型参数在编译时被删除。