2012-07-28 12 views
1
ArrayList<classA> aList = /*I then fill this array*/ 
    ArrayList<classB> bList = /* I then fill this array too*/ 

    /*Now put them both in the following ArrayList of Objects*/ 
    ArrayList<Object> myObjs = new ArrayList<Object>(); 
    myObjs.add(aList); 
    myObjs.add(bList); 

    /*The following two lines however fails at run time*/ 
    ArrayList<classA> x = (ArrayList<classA>) myObjs.get(0); 
    ArrayList<classB> x = (ArrayList<classB>) myObjs.get(1); 

我刚刚从另一个线程读取为什么下面向下铸造在Java中是行不通的:

任何一个可以请告诉我“时,有它成功的在运行时可能向下转换允许”上面代码的问题? 非常感谢你!

+2

这是因为Java集合不是协变的。 'List '不是'List '的子类型,尽管'Foo'是'Object'的子类型。 – 2012-07-28 14:10:55

+0

如果你有问题的答案,你可能应该这样发布。 – 2012-07-28 14:13:27

回答

2

Java Tutorials on Generics

考虑以下方法:

public void boxTest(Box<Number> n) { /* ... */ } 

它接受什么类型的参数?通过查看它的签名,可以看到它接受了一个类型为Box<Number>的参数。但是,这是什么意思?你可以像你期望的那样通过Box<Integer>Box<Double>吗?答案是“否”,因为Box<Integer>Box<Double>不是Box<Number>的子类型。

换句话说:即使classAObject一个亚类中,ArrayList<classA>ArrayList<Object>子类型。

+3

这就是“Java集合不协变”的含义。 – 2012-07-28 14:10:00

0

问题是铸造一个ObjectclassA是不一样的铸造ArrayList<Object>ArrayList<classA>。另外,您应该使用类名称作为模板参数,而不是对象名称。

+0

“另外,您应该使用类名作为模板参数,而不是对象名称”: 是的,这是正确的,我只是在发布问题时犯了错误。 – LeTex 2012-07-28 14:16:23

0

我看到这是一个有趣的问题。我一直在摆弄一个示例代码,这个工程!你可以在这个神奇的在线IDE工具中尝试这段代码 - http://ideone.com/,它可以免费在线编译和显示你的代码的输出。

import java.util.List; 
import java.util.ArrayList; 

class MyClass{ 

public static void main(String []args){ 

ArrayList<Integer> a = new ArrayList<Integer>(); 
a.add(10); 
a.add(100); 

ArrayList<String> b = new ArrayList<String>(); 
b.add("10"); 
b.add("100"); 

ArrayList<ArrayList> o = new ArrayList<ArrayList>(); 
o.add(a); 
o.add(b); 

a = o.get(0); 
b= o.get(1); 

System.out.println("int"+a.get(0)); 
System.out.println("string"+b.get(0)); 

System.out.println("Online IDE Works"); 
} 

} 

问题是你有一个ArrayList的ArrayList本身。向下转换不适用于对象到ArrayLists。但是,正如在上面的示例代码中,如果您将参数作为ArrayList本身提供,而不提供内部ArrayList的泛型类型,那么您将获得完美的输出结果!

+0

在我的情况下(如果可能)铸造是必须的,因为我将使用它的对象调用classA的方法,否则这是不可能的。 – LeTex 2012-07-28 15:35:33

+0

是的,我只是试着用= =(ArrayList )o.get(0);和b =(ArrayList )o.get(1)。它确实有用! – afrin216 2012-07-28 15:43:13

+0

是的,它会适用于你所说的:(将ArrayList 向下投射到ArrayList ),这就是为什么有些人在此之前说过“当在运行时有可能成功进行向下转换” 但在我的情况演员阵容是从ArrayList 到ArrayList ,这就是问题发生的地方:“Java集合不是协变的”,这反过来又是由于集合是可变的。 – LeTex 2012-07-28 21:58:21