列表中的泛型类型转换

时间:2013-12-18 05:13:17

标签: java generics casting

为什么不编译以下代码?我知道将它更改为String工作,但为什么我们无法从字符串到对象进行类型转换?

List<Object> c4 = new ArrayList<String>();

5 个答案:

答案 0 :(得分:6)

使用泛型时,继承概念略有不同。您需要使用wildcards and sub typing来实现泛型的继承。

根据oracle tutorial

  

注意:给定两种具体类型A和B(例如,Number和   整数),MyClass<A>MyClass<B>无关,无论如何   A和B是否相关。 MyClass<A>的共同父母   并且MyClass<B>是对象。

答案 1 :(得分:1)

虽然StringObject的子类,但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}}。

仿制药的发明部分是为了不会发生这种情况。 BohemianNambari有技术原因。

答案 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>,那么你可以做任何事情来打破他们的权力。