问题1: 鉴于:
List<Object> lo = new ArrayList<Object>();
如果我理解正确,ArrayList<>()
中的参数必须为Object
,那么我们是否需要编写它?或者我们就这样跳过它:
List<Object> lo = new ArrayList<>();
问题2: 鉴于:
List<? extends Animal> myArray = new ArrayList<Dog>();
据我了解,=
的左侧表示myArray
是List
类型的引用,可以是List<Cat>
或List<Dog>
,... .. =
的右侧怎么样,这意味着什么?这是否意味着引用myArray
被分配给仅包含List
的{{1}}的真实对象?如果是,我不能不考虑Dog
右侧的信息是有用还是必要的情况。你能举个例子吗
=
是必不可少的还是至少有用的?
答案 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)
List<? extends Number>
中所示),就可以这样做。例如:
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中,类型参数在编译时被删除。