我可以使用Class.newInstance()构造函数参数吗?

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

163694 次浏览

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

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

编辑:根据评论似乎指向类和方法名是不够的一些用户。要了解更多信息,请查看得到constuctor调用它的文档。

MyClass.class.getDeclaredConstructor(String.class).newInstance("HERESMYARG");

obj.getClass().getDeclaredConstructor(String.class).newInstance("HERESMYARG");

不要使用Class.newInstance();请看这个线程:为什么Class.newInstance()是邪恶的?

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

你可以使用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;
}
}
我认为这正是你想要的 http://da2i.univ-lille1.fr/doc/tutorial-java/reflect/object/arg.html < / p >

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

假设您有以下构造函数

class MyClass {
public MyClass(Long l, String s, int i) {


}
}

你需要像这样表明你打算使用这个构造函数:

Class classToLoad = MyClass.class;


Class[] cArg = new Class[3]; //Our constructor has 3 arguments
cArg[0] = Long.class; //First argument is of *object* type Long
cArg[1] = String.class; //Second argument is of *object* type String
cArg[2] = int.class; //Third argument is of *primitive* type int


Long l = new Long(88);
String s = "text";
int i = 5;


classToLoad.getDeclaredConstructor(cArg).newInstance(l, s, i);

按照以下步骤调用参数化构造函数。

    通过在Class[]中传递类型来获取带有参数类型的Constructor for ClassgetDeclaredConstructor方法
  1. 通过在Object[]中传递
    的值创建构造函数实例 Constructor
  2. 方法

示例代码:

import java.lang.reflect.*;


class NewInstanceWithReflection{
public NewInstanceWithReflection(){
System.out.println("Default constructor");
}
public NewInstanceWithReflection( String a){
System.out.println("Constructor :String => "+a);
}
public static void main(String args[]) throws Exception {


NewInstanceWithReflection object = (NewInstanceWithReflection)Class.forName("NewInstanceWithReflection").newInstance();
Constructor constructor = NewInstanceWithReflection.class.getDeclaredConstructor( new Class[] {String.class});
NewInstanceWithReflection object1 = (NewInstanceWithReflection)constructor.newInstance(new Object[]{"StackOverFlow"});


}
}

输出:

java NewInstanceWithReflection
Default constructor
Constructor :String => StackOverFlow

这就是我如何使用动态构造函数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();
}
}