use*_*518 30 java generics casting
考虑下面doSomething(List<Object>)接受List<Object>作为参数的方法.
private void doSomething(List<Object> list) {
// do something
}
Run Code Online (Sandbox Code Playgroud)
现在考虑下面的代码片段,它试图调用doSomething()我尝试传递List<String>给的地方doSomething()
List<Object> objectList;
List<String> stringList;
doSomething(stringList); // compilation error incompatible types
doSomething(objectList); // works fine
Run Code Online (Sandbox Code Playgroud)
即使在代码下面也会引发编译错误
objectList = stringList; // compilation error incompatible types
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么List<String>不能传递给接受的方法List<Object>?
Ahm*_*leh 43
因为虽然String延伸Object,List<String>但不延伸List<Object>
更新:
通常,如果Foo是子类型(子类或子接口)Bar,并且G是一些泛型类型声明,则不是G<Foo>子类型的情况G<Bar>.
这是因为收藏品确实发生了变化 在您的情况下,如果List<String>是子类型List<Object>,则String在使用其超类型引用列表时,可以将其他类型添加到其中,如下所示:
List<String> stringList = new ArrayList<String>;
List<Object> objectList = stringList;// this does compile only if List<String> where subtypes of List<Object>
objectList.add(new Object());
String s = stringList.get(0);// attempt to assign an Object to a String :O
Run Code Online (Sandbox Code Playgroud)
并且Java编译器必须防止这些情况.
有关此 Java Tutorial页面的更多详细说明.
Mar*_*o13 17
您可以将错误类型的对象放入列表中,如果这有效:
private void doSomething(List<Object> list) {
list.add(new Integer(123)); // Should be fine, it's an object
}
List<String> stringList = new ArrayList<String>();
doSomething(stringList); // If this worked....
String s = stringList.get(0); // ... you'd receive a ClassCastException here
Run Code Online (Sandbox Code Playgroud)
Shi*_*mar 10
对于任何不熟悉泛型的人来说,Java中的这个通用问题可能看起来很混乱,因为乍一看它看起来像是对象,所以List<String>可以在List<Object>需要的地方使用,但事实并非如此.这将导致编译错误.
这有一定道理,如果你走一步,因为List<Object> 可以存储任何东西,包括String,Integer等,但List<String>只能存储Strings.
另请看:为什么不从List <T>继承?
这些限制的原因与方差考虑有关。
采取以下代码:
public void doSomething(List<Object> objects)
{
objects.add(new Object());
}
Run Code Online (Sandbox Code Playgroud)
扩展您的示例,您可以尝试执行以下操作:
List<String> strings = new ArrayList<String>();
string.add("S1");
doSomething(strings);
for (String s : strings)
{
System.out.println(s.length);
}
Run Code Online (Sandbox Code Playgroud)
希望很明显,如果编译器允许编译此代码(但事实并非如此),为什么这会中断 -当尝试将 转换为 aClassCastException时,列表中的第二项会出现aObjectString。
为了能够传递通用集合类型,您需要执行以下操作:
public void doSomething(List<?> objects)
{
for (Object obj : objects)
{
System.out.println(obj.toString);
}
}
Run Code Online (Sandbox Code Playgroud)
同样,编译器正在注视着您,如果您将 替换System.out为objects.add(new Object())编译器,编译器将不允许这样做,因为objects可能已创建为List<String>.
有关方差的更多背景信息,请参阅维基百科文章协方差和逆变
| 归档时间: |
|
| 查看次数: |
17042 次 |
| 最近记录: |