创建类的实例并初始化其所有字段

时间:2013-11-26 10:29:11

标签: java reflection jaxb

我想创建一个类的实例,但我还需要递归地初始化它的所有字段。

你看到的相关代码是objectFactory,因为这些类中的一些可能是JAXB类,所以对于每个包都有一个ObjectFactory,其方法如createJaxbObject(....)。

编辑:

我的最终解决方案就是这个:

public Object getInstance(Class<?> instanceClass, Boolean simple,
        String jaxbName) {

    Object instance = null;
    try {
        if (instanceClass.isPrimitive())
            return primitiveValues.get(instanceClass.getName());
        if (List.class.isAssignableFrom(instanceClass))
            return new ArrayList();
        else if (instanceClass.isEnum())
            return instanceClass.getEnumConstants()[0];
        else if (instanceClass.isArray())
            return java.lang.reflect.Array.newInstance(instanceClass, 1);
        else if (BigInteger.class.isAssignableFrom(instanceClass))
            return new BigInteger("0");
        else if (instanceClass.equals(String.class))
            return "";
        else if (instanceClass.equals(Boolean.class))
            return false;
        else if (instanceClass.equals(EntityObjectStringType.class))
            return new EntityObjectStringType();
        else if (JAXBElement.class.isAssignableFrom(instanceClass)) {
            try {
                Method m = null;
                Class<?> objFactoryClass = null;
                Iterator<String> it = EditorServlet.objectFactories
                        .iterator();
                Object of = null;
                while (it.hasNext()) {
                    objFactoryClass = Class.forName(it.next());
                    of = objFactoryClass.getConstructor().newInstance();
                    m = getMethodFromObjectFactory(objFactoryClass,
                            jaxbName);
                    if (m != null)
                        if (m.getParameterTypes().length > 0)
                            break;
                }
                Object jaxbElement = getInstance(m.getParameterTypes()[0],
                        m.getParameterTypes()[0].getSimpleName());
                return m.invoke(of, jaxbElement);

            } catch (NoSuchMethodException e) {
                logger.error("JAXB NoSuchMethodException");
            }
        } else
            try {
                logger.info("Costruttori per " + instanceClass.getName()
                        + " " + instanceClass.getConstructors().length);
                instance = instanceClass.getConstructor().newInstance();
            } catch (NoSuchMethodException noSuchMethodException) {
                logger.error("getConstructors NoSuchMethodException");
            }
    } catch (IllegalArgumentException e) {
        logger.error("IllegalArgumentException " + instanceClass.getName());
    } catch (SecurityException e) {
        logger.error("SecurityException " + instanceClass.getName());
    } catch (InstantiationException e) {
        logger.error("InstantiationException " + instanceClass.getName()
                + " " + instanceClass.isPrimitive());
    } catch (IllegalAccessException e) {
        logger.error("IllegalAccessException " + instanceClass.getName());
    } catch (InvocationTargetException e) {
        logger.error("InvocationTargetException " + instanceClass.getName());
    } catch (ClassNotFoundException e) {
        logger.error("ClassNotFoundException " + instanceClass.getName());
    }
    if (!simple) {
        for (Field field : instanceClass.getDeclaredFields()) {
            try {
                Object fieldInstance = getInstance(field.getType(),
                        field.getName());
                field.setAccessible(true);
                field.set(instance, fieldInstance);
            } catch (IllegalArgumentException e) {
                logger.error("IllegalArgumentException "
                        + instanceClass.getName());
            } catch (IllegalAccessException e) {
                logger.error("IllegalAccessException "
                        + instanceClass.getName());
            }
        }
    }

    return instance;
}

2 个答案:

答案 0 :(得分:1)

如果我可以冒险猜测,你会在NoSuchMethodException捕获中递归调用你的方法。

Object of = getInstance(objFactoryClass);

如果您的递归调用仍未找到该方法:

Method m = getMethodFromObjectFactory(objFactoryClass, c);

...该方法将再次调用自身,在某些时候应该以{{1​​}}结束。

答案 1 :(得分:1)

您的递归没有断点

尝试在类为主类型的地方停止递归:

    if (List.class.isAssignableFrom(c))
        instance = new ArrayList();
    else if (c.isEnum())
        return c.getEnumConstants()[0]; //avoid stackoverflow error
    else if(c.isPrimitive()) {
        instance = c.getConstructor().newInstance();
        // use must stop here
        return instance;
    } else{
        instance = c.getConstructor().newInstance();
    }

isPrimitive将判断class是否为主要类型(int,Integer,shor,Short,String ...)