首先,我对思考还很陌生。我一直在做一个大型项目,我需要在某些部分使用反射(是的,我肯定需要它)。所以我想,我应该创建一个反射助手类,它将能够在我的项目中创建具有任意数量参数的任何类的新实例。
作为我的问题的一个例子:通常(据我所知),创建一个在其构造函数中有2个字符串作为参数的类的实例;
Class.getConstructor(String.class, String.class).newInstance("Arg_1", "Args_2");
就能完成这项工作。然而,在我的例子中,我需要一个方法,它可以用于任何具有任何构造函数的类。所以我创建了这些方法,但它似乎不起作用,我一直得到NoSuchMethodException
。我需要帮助才能让它起作用。
private static String packagePrefix = "com.***";
public static Class<?> getClass(String className) throws ClassNotFoundException {
return Class.forName(packagePrefix + "." + className);
}
public static Object getClassInstance(String className, Object... args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
Class<?>[] cArgs = new Class[args.length];
for (int i = 0; i < args.length; i++) {
cArgs[i] = args[i].getClass();
}
return getClass(className).getConstructor(cArgs).newInstance(args);
}
发布于 2017-08-25 19:29:23
一般来说,你不能“用任意数量的参数创建任何类的新实例”。如果没有这样的构造函数,那么你将无法调用它。
接下来,Class.getConstructor
查找具有给定形参类型的构造函数,而不是与赋值兼容的类型。所以,如果你有Foo(Number)
,你不会在Foo.class.getConstructor(Long.class)
中找到这个构造器。您必须遍历Class.getConstructors
并搜索构造函数,该构造函数具有参数类型、与赋值兼容的参数类型。
幸运的是,这已经被做了一千次了。例如,参见来自Commons BeanUtils的ConstructorUtils.invokeConstructor。其实现远非微不足道。
发布于 2017-08-25 22:40:40
在你的评论中,你说你有一个接受4个参数的类
Skill(Monster m, Integer procChance, Integer duration, Integer severity)
但您尝试仅使用3个参数来反射地创建它:
Skill skill = (Skill) ReflectionHelper.getClassInstance(skillPackagePrefix + skillType.getName(), monster, procChance, params);
即使param
是一个包含2个整数的数组(正如您所注释的),它也会被Java视为数组参数,并且不会被合并到Object... args
变量中。上面的代码只适用于下面的构造函数:
Skill(Monster m, Integer procChance, Integer[] params)
https://stackoverflow.com/questions/45887927
复制