我想使用class . newinstance(),但我实例化的类没有null构造函数。因此,我需要能够传入构造函数参数。有办法做到这一点吗?


当前回答

不要使用Class.newInstance();为什么Class.newInstance()是邪恶的?

像其他答案说,使用Constructor.newInstance()代替。

其他回答

我觉得这正是你想要的 http://da2i.univ-lille1.fr/doc/tutorial-java/reflect/object/arg.html

虽然它看起来是一条死线,但有人可能会发现它有用

可以使用getConstructor(…)获取其他构造函数。

myObject.getClass().getDeclaredConstructors(types list).newInstance(args list);

编辑:根据评论似乎指向类和方法名是不够的一些用户。要了解更多信息,请参阅获取构造函数并调用它的文档。

你可以使用Class的getDeclaredConstructor方法。它需要一个类数组。下面是一个经过测试的工作示例:

public static JFrame createJFrame(Class c, String name, Component parentComponent)
{
    try
    {
        JFrame frame = (JFrame)c.getDeclaredConstructor(new Class[] {String.class}).newInstance("name");
        if (parentComponent != null)
        {
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
        else
        {
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        }
        frame.setLocationRelativeTo(parentComponent);
        frame.pack();
        frame.setVisible(true);
    }
    catch (InstantiationException instantiationException)
    {
        ExceptionHandler.handleException(instantiationException, parentComponent, Language.messages.get(Language.InstantiationExceptionKey), c.getName());
    }
    catch(NoSuchMethodException noSuchMethodException)
    {
        //ExceptionHandler.handleException(noSuchMethodException, parentComponent, Language.NoSuchMethodExceptionKey, "NamedConstructor");
        ExceptionHandler.handleException(noSuchMethodException, parentComponent, Language.messages.get(Language.NoSuchMethodExceptionKey), "(Constructor or a JFrame method)");
    }
    catch (IllegalAccessException illegalAccessException)
    {
        ExceptionHandler.handleException(illegalAccessException, parentComponent, Language.messages.get(Language.IllegalAccessExceptionKey));
    }
    catch (InvocationTargetException invocationTargetException)
    {
        ExceptionHandler.handleException(invocationTargetException, parentComponent, Language.messages.get(Language.InvocationTargetExceptionKey));
    }
    finally
    {
        return null;
    }
}

这就是我如何使用动态构造函数args list创建Class clazz的实例。

final Constructor constructor = clazz.getConstructors()[0];
final int constructorArgsCount = constructor.getParameterCount();
if (constructorArgsCount > 0) {
    final Object[] constructorArgs = new Object[constructorArgsCount];
    int i = 0;
    for (Class parameterClass : constructor.getParameterTypes()) {
        Object dummyParameterValue = getDummyValue(Class.forName(parameterClass.getTypeName()), null);
        constructorArgs[i++] = dummyParameterValue;
    }
    instance = constructor.newInstance(constructorArgs);
} else {
    instance = clazz.newInstance();
}

这就是getDummyValue()方法的样子,

private static Object getDummyValue(final Class clazz, final Field field) throws Exception {
    if (int.class.equals(clazz) || Integer.class.equals(clazz)) {
        return DUMMY_INT;
    } else if (String.class.equals(clazz)) {
        return DUMMY_STRING;
    } else if (boolean.class.equals(clazz) || Boolean.class.equals(clazz)) {
        return DUMMY_BOOL;
    } else if (List.class.equals(clazz)) {
        Class fieldClassGeneric = Class.forName(((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0].getTypeName());
        return List.of(getDummyValue(fieldClassGeneric, null));
    } else if (USER_DEFINED_CLASSES.contains(clazz.getSimpleName())) {
        return createClassInstance(clazz);
    } else {
         throw new Exception("Dummy value for class type not defined - " + clazz.getName();
    }
}