查看下面的Crud对象代码,我期待的是类型为T的Field对象数组。我实际得到的是Object类型的Field对象的空数组。我的测试类叫做Timezone。所以,当我实例化Crud对象时,它看起来像......
Crud<Timezone> tz = new Crud<Timezone>();
但正如我所说,这不起作用。帮助赞赏。
import java.util.*;
import java.lang.reflect.*;
public class Crud<T> {
public T getInstance()
{
@SuppressWarnings("unchecked")
T object = (T) new Object();
return object;
}
public ArrayList<String> getMembers() {
ArrayList<String> retval = new ArrayList<String>();
try {
T object = this.getInstance();
Field[] fields = object.getClass().getDeclaredFields(); //Always empty
for (Field field : fields) {
retval.add(field.getName());
}
} catch (Exception e) {
System.out.println(e);
}
return retval;
}
}
答案 0 :(得分:2)
即使没有泛型,也不能做这样的事情:
Timezone object = (Timezone) new Object();
new Object()
将创建一个运行时类型为Object
的对象。这将包含Object
所有的所有字段和方法,但没有其他字段和方法。创建Object
后,不能使用强制转换将对象神奇地转换为其他类型;这将涉及添加Timezone
所具有的所有新字段和方法,而Java无法做到这一点。
所以这也不可行:
T object = (T) new Object();
不幸的是,Java也不允许你这样做:
T object = new T();
因为“类型擦除”。有关解决此问题的一些想法,请参阅Create instance of generic type in Java?(除非没有泛型的解决方案适合您)。
答案 1 :(得分:2)
不,由于type erasure,您无法在运行时访问该类型。
但是,有一种模式可以解决创建泛型类型实例的问题;您必须将类型标记传递给构造函数:
public class Crud<T> {
private Class<T> clazz;
public Crud(Class<T> clazz) {
this.clazz = clazz;
}
public T getInstance() {
return clazz.newInstance();
}
答案 2 :(得分:1)
如果您想要包装实例并获取其字段,则无需使用泛型。您可以使用Object
作为基类来允许包装器中的任何类型的对象。例如
public class Crud {
private final Object object;
public Crud(final Object someObject) {
this.object = someObject;
}
public ArrayList<String> getMembers() {
ArrayList<String> retval = new ArrayList<String>();
try {
Field[] fields = this.object.getClass().getDeclaredFields();
for (Field field : fields) {
retval.add(field.getName());
}
} catch (Exception e) {
System.out.println(e);
}
return retval;
}
}
然后你就做了
Crud tz = new Crud(new Timezone());
答案 3 :(得分:0)
您可能应该在Timezone类中专门为Timezone实现方法getDeclaredFields()
。
答案 4 :(得分:0)
我们可以像这样定义泛型类:
public class Crud<T> {
private final Class<T> mClass;
public Crud(Class<T> tClass)
{
mClass = tClass;
}
public T getInstance() throws Exception
{
T object = mClass.newInstance();
return object;
}
...
}
然后我们可以像这样使用它:
try
{
Date tDate = new Crud<Date>(Date.class).getInstance();
System.out.println("Date: " + tDate);
}
catch(Exception e)
{
System.out.println("Error: " + e);
}
输出:Date: Mon Feb 24 21:00:04 PST 2014