因此,假设我们有一个Java应用程序,其中包含一个名为SomeAbstractClass
的抽象类,以及至少10个超类的子类。
在Collection<? extends SomeAbstractClass>
的方式中使用这个抽象超类在泛型中的用法是什么,而不仅仅是使用Collection<SomeAbstractClass>
也许我错过了仿制药中非常基本的东西。
答案 0 :(得分:4)
这两个声明之间的区别:
Collection<? extends A> c1;
Collection<A> c2;
c2是否可以包含A或任何子类的实例,但是c1可以包含某个未知但是特定的A(或A)子类或任何未知类的子类的实例。
您无法将项目添加到c2,因为编译器不知道它是什么类型,只有当您获得一个时它才可以转换为A。
此外,你不能将c1指定(即强制转换)为c2 - c1不是c2类型的子类。
答案 1 :(得分:1)
泛型中的通配符用于Collection Type,通常不用于存储的元素。
例如,想象一个采用参数List<Number>
的方法。
public void calculateSum(List<Number> numbers) {
for (Number n: numbers) {
// calculate Sum
}
}
现在,如果我们想通过传递List<Integer>
来计算整数之和,如下所示。 (请注意,Integer
是Number
)
List<Integer> integers= new ArrayList<Integer>();
//Populate collection
calculateSum(integers); //Error
即使Integers
是[{1}} Number
的子类型不是List<Integers>
的子类型,这也不会起作用。请注意,List<Number>
仍然可以存储List<Number>
,Integer
,Float
等。
因此,要使用通用方法计算任何类型Double
的总和,我们使用通配符,如下所示
Number
如果类型扩展public void calculateSum(List<? extends Number> numbers) {
for (Number n: numbers) {
// calculate Sum
}
}
答案 2 :(得分:0)
Collection<? extends SomeAbstractClass>
^
|
|
Collection<SomeAbstractClass>
Collection<? extends SomeAbstractClass>
和Collection<SomeAbstractClass>
是完全不同的类型,不相关。
请注意,
给出两个具体类型A和B(例如,Number和Integer), MyClass与MyClass没有任何关系,无论是否 不是A和B是相关的。
例如,List<Integer>
不是List<Number>
的子类型,即使Integer是Number的子类型。
答案 3 :(得分:-2)
在你的情况下它没有区别,因为类型是抽象的,但一般Collection<SomeClass>
可以包含SomeClass
及其所有子类,而Collection<? extends SomeClass>
不能包含SomeClass
但只有它子类。
你可以自己试试。
List<Number> foo = new ArrayList<>();
foo.add(Integer.valueOf(0));
工作时
List<? extends Number> foo = new ArrayList<>();
foo.add(Integer.valueOf(0));
没有。它显示错误"The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (Integer)"