我一定错过了关于Java中泛型的东西,但为什么这不起作用?
List<String> list = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)
无法发送至:
method( List<Object> );
Run Code Online (Sandbox Code Playgroud)
但它不起作用?怎么会?
但如果方法是:
method( Object o )
Run Code Online (Sandbox Code Playgroud)
它可以用于:
method( new String("hello") )
Run Code Online (Sandbox Code Playgroud)
没有任何问题
q1)String确实扩展了Object,为什么不能传递给它?
List<Object>
Run Code Online (Sandbox Code Playgroud)
q2)为什么会这样
method( List<? extends Object> )
Run Code Online (Sandbox Code Playgroud)
工作?有什么不同?
Bom*_*mbe 10
看这个:
List<String> stringList = new ArrayList<String>();
List<Object> objectList = stringList; // if this was allowed…
objectList.add(new Object());
String s = stringList.get(0); // …this would throw a ClassCastException
Run Code Online (Sandbox Code Playgroud)
显然,这不能被允许工作,因为List<String>它将包含一个Object后来,抛弃了泛型旨在给你的所有类型安全.
List<String>List<Object>由于其他答案中提到的原因,它不是您所预期的子类型.但是,您可以像这样定义方法:
method(List<? extends String> list)
Run Code Online (Sandbox Code Playgroud)
这将允许您从列表中获取字符串,但不能放入任何内容.您可以将List<String>或者理论上将任何String子类型的List 传递给方法.您也可以将其定义为
method(List<? super String> list)
Run Code Online (Sandbox Code Playgroud)
这将允许您将字符串放入列表中,但只能从中读取对象.然后你可以传入一个List<String>或一个List<Object>.请注意,在此示例中没有多大意义(因为您不能将String子类化),但它对其他类型层次结构有意义
如果method()被定义为这样怎么办?
void method(List<Object> list) {
list.add(new Long(1));
}
Run Code Online (Sandbox Code Playgroud)
那没关系吗?哎呀,除非你通过了一个清单<String>!
解释直觉很难,但我可以指出List上的get()方法不会出现这样的问题,对吧?由于list只承诺返回一个Object.问题是"设置"或"添加"方法.它需要匹配超类型,而不是子类型.一般来说,限制种类在泛型土地上是双向的.所以它与简单的参数传递不同,其中子类总是正常的.