如何用泛型实例化java中的类实例



如何用泛型在java中实例化类实例?

我正在尝试从XML文件中读取数据,然后实例化一个对象,以便将该对象的其他属性(从XML文件读取)添加到该对象中。我认为最简单的方法(这样我就不必读取类方法名称并找到setter)是用构造函数中的所有值实例化对象。

我正在尝试这样做,所以我需要这样的东西:T obj = new Object(),但要获得对象类

    private static final boolean string_field = true;
    private static <T> T getObject(Element e, String[] fieldNames, boolean[] fieldTypes) {
        Object[] values = new Object[fieldNames.length];
        for (int i=0; i<fieldNames.length; i++) {
            values[i] = (fieldTypes[i]==string_field)? getStringValue(e, fieldNames[i])
                    : getIntegerValue(e, fieldNames[i]);
        }
        return new T(values);
    }

谢谢你的建议。

编辑:

这是我更新的代码(未经测试):

    public static <T> List<T> populateObjectList(Document xmlDoc, String tagName,
            Class clazz, String[] fieldNames, Class[] fieldTypes) {
        List<T> objList = new ArrayList<T>();
        NodeList nl = xmlDoc.getElementsByTagName(tagName);
        if (nl!=null && nl.getLength()>0) {
            for (int i=0; i<nl.getLength(); i++) {
                Element e = (Element) nl.item(i);
                T t;
                try {
                    t = getObject(e, clazz, fieldNames, fieldTypes);
                    objList.add(t);
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (IllegalArgumentException ex) {
                } catch (InvocationTargetException ex) {
                } catch (NoSuchMethodException ex) {
                }
            }
        }
        return objList;
    }
    private static <T> T getObject(Element e, Class clazz, String[] fieldNames, Class[] fieldTypes)
            throws InstantiationException, IllegalAccessException, IllegalArgumentException,
            InvocationTargetException, NoSuchMethodException {
        Object[] initargs = new Object[fieldNames.length];
        for (int i=0; i<fieldNames.length; i++) {
            initargs[i] = (fieldTypes[i].getName().equals("int"))?
                getIntegerValue(e, fieldNames[i])
                : getStringValue(e, fieldNames[i]);
        }
        return (T) clazz.getConstructor(fieldTypes).newInstance(initargs);
    }

我发布这个是为了让你们中的一些人理解我想做什么。

再次感谢大家的建议。

不能实例化泛型类型。Java泛型有一个令人讨厌的特性,称为类型擦除,这基本上意味着JVM不知道在运行时泛型类或方法使用了什么类型。这是为了与泛型类的前泛型版本(如集合)向后兼容。

您可以做的是将Class<T> clazz添加到您的参数列表中,然后将方法的末尾替换为:

Class<?>[] paramTypes = new Class[values.length];
for (int i = 0; i < paramTypes.length; i++) {
    paramTypes[i] = values[i].getClass();
}
return clazz.getConstructor(paramTypes).newInstance(values);

如果类没有按正确顺序采用正确类型和数量的参数的构造函数,则会引发异常。

CAVEAT:只有当构造函数的参数类型与对象类型完全相同时,这才有效。例如,如果values{ "Hello", new Integer(2) }组成,那么它将只找到签名为SomeClass(String, Integer)的构造函数,而找不到签名为SomeClass(Object, Object)的构造函数。

您怎么知道T包含一个接受单个Object[]参数的构造函数?解决这个问题的方法是通过一个抽象的工厂。

interface ThingFactory { // Choose an appropriate name.
    T create(Object[] values);
}
private static <T> T getObject(
    ThingFactory<T> factory, Element e, String[] fieldNames, boolean[] fieldTypes
) { 
    ...
    return factory.create(values);
}

现在T可能甚至没有一个相当奇怪的Object[]构造函数。CCD_ 11可能是一个抽象类型。工厂可能会根据参数返回不同的类型。也许有时这些产品是可以缓存的不可变对象。

您不能执行new T(),因为在运行时,T实际上只是Object。编译器使用泛型进行类型检查(例如,不能将Integer放入List<String>),但随后会丢弃泛型信息。所有类型的参数都有一个已编译的方法副本,因此它无法知道您希望它实例化哪种类型。

有关类型擦除的详细信息,请阅读。

我真的看不出你的问题,是不是不可能使用obj.getClass?

最新更新