注意,ArrayList<A> and ArrayList<? extends A>它们用于声明变量或参数(不用于创建新的泛型类).
声明对象属性时,两个表达式是否等效(案例1)?:
class Foo {
private ArrayList<A> aList; // == ArrayList<? extends A> aList;
}
Run Code Online (Sandbox Code Playgroud)
编辑:从允许添加哪种对象的角度来看,两个表达式是否相同aList?,但与下列情况的意义不同?
但在参数声明(案例2)中使用时它们是不同的?:
void methodFoo(ArrayList<A> al) != void methodFoo(ArrayList<? extends A> al)
Run Code Online (Sandbox Code Playgroud)
因为第一个只允许传递ArrayList对象,而第二个就像允许发送的"更宽容"
ArrayList<A1>并且ArrayList<A2>(只要A1和A2扩展A)?
如果这是正确的,那么这两个表达式是否有效地存在其他情况?
谢谢,
我们来看看一些实际的例子.说,你有:
List<Number> list;
Run Code Online (Sandbox Code Playgroud)
这意味着无论分配给此变量或字段的是什么都需要Number输出Number,因此您始终知道会发生什么.Integer自Integer扩展以来可以添加到此列表中Number.但是,您无法分配ArrayList<Long>此列表.
但请考虑这种情况:
List<? extends Number> list;
Run Code Online (Sandbox Code Playgroud)
这个说:嘿,这是一个扩展的东西的列表Number,但没有人知道究竟是什么.这是什么意思?这意味着您可以分配例如ArrayList<Long>此列表,在第一种情况下您不能.你还知道,无论这个列表输出将是一个Number,但你不能把一个Integer在它了.
还有一个相反的情况:
List<? super Number> list;
Run Code Online (Sandbox Code Playgroud)
打印你说:那是一个列表Number或它的超类.这就是反之亦然的一切.该列表现在可以引用ArrayList<Object>和ArrayList<Number>.现在我们不知道这个列表会输出什么.会是一个Number?会是一个Object吗?但是,现在我们知道,我们可以把一个Number在此列表以及任何子Number像Integer或Long.
顺便说一句,有一条规则说生产者延伸,消费者超级(简称PECS).如果您需要列表来输出值,那么它就是生产者,这是第二种情况.如果您需要列表接受值,那么它是消费者,这是第三种情况.如果您需要两者,请不要使用通配符(这是第一种情况).
我希望这能解决问题.
| 归档时间: |
|
| 查看次数: |
906 次 |
| 最近记录: |