为什么不编译以下代码?我知道将它更改为String工作,但为什么我们无法从字符串到对象进行类型转换?
List<Object> c4 = new ArrayList<String>();
答案 0 :(得分:6)
使用泛型时,继承概念略有不同。您需要使用wildcards and sub typing来实现泛型的继承。
注意:给定两种具体类型A和B(例如,Number和 整数),
MyClass<A>
与MyClass<B>
无关,无论如何 A和B是否相关。MyClass<A>
的共同父母 并且MyClass<B>
是对象。
答案 1 :(得分:1)
虽然String
是Object
的子类,但List<String>
不是 List<Object>
的子类。
原因是如果它是一个子类,它将允许以下内容:
List<String> listA = new ArrayList<String>();
List<Object> listB = listA; // normally a compile error
listB.add(new Integer(1)); // it would allow this
String s = listA.get(0); // boom! ClassCastException
答案 2 :(得分:1)
假设这有效
List<Object> c4 = new ArrayList<String>();
然后你可以去添加
c4.add(new YourCrazyObjectThatIsNotAString());
这没有意义,因为c4
应该是ArrayList
的{{1}}。
答案 3 :(得分:1)
List<Object> c4 = new ArrayList<String>();
现在你可以添加任何Object,这在技术上是每个Object。这是不正确的,因为List确实是String。因此不允许这样做。
因此,假设您在列表中添加了一些自定义对象。然后在获取对象时,它将尝试类型转换为String,这会抛出不正确的强制转换异常。为了避免这种歧义,java不允许这样做。
一般
List<SomeObject> l = new ArrayList<SubClassOfSomeObjectClass>;
是不允许的。但是,您可以执行类似
的操作List<? extends SomeObject> l = new ArrayList<SubClassOfSomeObject>;
答案 4 :(得分:0)
请考虑以下代码:
List<String> ls = new ArrayList<String>();
List<Object> lo = ls;
lo.add(new Integer(5));
String x = ls.get(0);
泛型是为了防止某些类转换异常而发明的。但是,如果可以将List<String>
分配给List<Object>
,那么你可以做任何事情来打破他们的权力。