3

问题 1:鉴于:

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

如果我理解正确的话, in 的参数ArrayList<>()必须是Object,所以我们需要写它吗?或者我们像这样跳过它:

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

问题2:给定:

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

=据我了解,手段的左侧myArray是类型的引用List,可以是List<Cat>or List<Dog>, .... 的右侧=呢,它是什么意思?这是否意味着将引用myArray分配给List仅包含的真实对象Dog?如果是,我不能不考虑右侧的信息=有用或必要的情况。你能给我一个例子吗

     ... = new ArrayList<Dog>();  

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

4

4 回答 4

2

第一个问题: Java 7 引入了菱形运算符,在大多数情况下,它充当了写出所有泛型类型的语法糖。它可以省略,但它“仍然存在”。

第二个问题:

  • 左侧是一个列表,它是一个上限通用通配符。它包含任何扩展或实现名为 的类的对象Animal除非将列表定义为下界通用通配符(使用super关键字),否则您将无法将任何值插入该列表。在这个 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>的是空的,无法添加。

于 2013-04-28T06:10:11.060 回答
2

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

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

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

如果你想实现这一点,你将不得不使用 super 关键字:List<? super SomeClass>

也可以看看:

于 2013-04-28T05:50:22.230 回答
1
  1. 只要您使用 Java 7,只要引用类型不包含通配符(如 中List<? extends Number>),您就可以这样做。
  2. 当您使用通配符时,您只能执行类型安全操作。在这种情况下,您可以从列表中读出。

例如:

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怎么办?

于 2013-04-28T05:41:48.390 回答
0

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

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

于 2013-04-28T05:38:38.503 回答