2010-05-28 113 views
0

我想获得对Collection中保存的Object类型的访问权限。以下是何时以及为什么我想要这样做的一个简单例子。这甚至有可能吗?获取类集合上元素的类型信息

List<Address> addressList = new LinkedList<Address>(); 

Main.addElement(addressList); 

Class Main{ 
    public void addElement(Object inArgument){ 
     List<Object> argument = (List<Object>)inArgument; 
     argument.add(/* WOULD LIKE TO CREATE A NEW OBJECT OF THE APPROPRIATE TYPE 
         HERE, IN THIS CASE, IT WOULD BE OF TYPE: "Address" */); 
    } 
} 

回答

5

不,你不能做到这一点与目前执行Java的泛型。类型参数在编译时被“擦除”。

通过反射,您可以确定方法参数和返回类型以及成员变量的类型参数信息,但在这种情况下无法帮助。

作为一种实用的解决方法,大多数想要执行类似操作的API都将Class实例作为第二个参数。例如:

public void addElement(Collection<T> c, Class<? extends T> clz) 
    throws Exception 
{ 
    Constructor<? extends T> ctor = clz.getConstructor(); 
    T el = ctor.newInstance(); 
    c.add(el); 
} 
+0

无赖。我想这是有道理的,因为列表只是一个引用的集合。值得怀疑的是,应用程序不需要知道引用在运行时指向的对象的类型。 – 2010-05-29 01:22:40

3

由于泛型细节在运行时不可用,因此无法使用当前方法定义的方式执行此操作。另一种方法是这样:

public <T> void addElement(List<T> inArgument, Class<? extends T> clazz){ 
    T t = clazz.newInstnace(); 
    inArgument.add(t); 
    // exception handling omitted for brevity 
} 

你再调用addElement这样

addElement(addressList, Address.class); 

见JLS的泛型类型的详细信息,以及类型擦除。在简单地说,类型擦除是responsbible针对此行为:在b==true

Vector<String> x = new Vector<String>(); 
Vector<Integer> y = new Vector<Integer>(); 
boolean b = x.getClass() == y.getClass(); 

结果。

0
argument.add(null); 

null是每一个引用类型的值:P

但严重的是,我不知道你为什么会想这样做。这意味着你的类型有某种“默认”值,这对一般类型来说并不是这样。

0

我不确定我是否理解你的问题,但我认为“超级”关键字在这里可能很有用。

List<Address> addressList = new LinkedList<Address>(); 
List<Object> stuffToSeeInWashington = new LinkedList<Object>(); 

Main.addWhiteHouse(addressList); 
Main.addWhiteHouse(stuffToSeeInWashington); 

Class Main{ 
    public void addWhiteHouse(List<? super Address> argument){ 
     Address whiteHouse = new Address("1600 Pennsylvania Ave"); 
     argument.add(whiteHouse) ; 
    } 
}