当参数是构造函数的参数声明类型的子类时,反射找不到构造函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当参数是构造函数的参数声明类型的子类时,反射找不到构造函数相关的知识,希望对你有一定的参考价值。
我正在使用反射来实例化特定需求的类。
目前的代码如下:
public final <T> T instanciate(Class<? extends T> a_clazz, Object... args) {
// Other stuff when no arg...
Class<?>[] l_argsClasses = getClassesFromObjects(args);
Constructor<?> constructor = a_clazz.getConstructor(l_argsClasses);
constructor.newInstance(args)
}
不幸的是,我读到,当给定的参数与构造函数声明中的类型不完全相同时,它将不起作用。
所以当我给出一个子类时,找不到构造函数,我得到一个NoSuchMethodException。
似乎这里没有处理多态的机制。
示例:
public class A {
}
public class B extends A {
}
public class Foo extends A {
public Foo(A a) {
}
}
将工作 :
instanciate(Foo.class, new A()); // because Foo(A a)
不会工作:
instanciate(Foo.class, new B()); // because Foo(B b) does't exists
您有解决此问题的任何解决方案吗?
谢谢
答案
java.beans
包有类Statement
和Expression
,可以使用子类型规则执行必要的查找:
Expression e = new Expression(Foo.class, "new", new Object[]{ new B() });
Foo foo = (Foo)e.getValue();
execute
method的文档描述了用于调用构造函数的特殊伪方法名称"new"
。
另一答案
我选择使用的解决方案是apache.commons.lang.reflect提供的方法
它提供了两个不同的版本:
- 需要完全匹配参数类型:invokeExact Constructor()
- 一个匹配参数类型通过赋值兼容性:invokeConstructor()
我已经进行了简单的测试并且它正在运行。所以我正在使用它。
结果如下:
public final <T> T instanciate(Class<? extends T> clazz, Object... args) {
try {
return clazz.cast(ConstructorUtils.invokeConstructor(clazz, args));
} catch (Exception e) {
throw new RuntimeException("Failed to instanciate Object", e);
}
}
非常简单的代码很好
以上是关于当参数是构造函数的参数声明类型的子类时,反射找不到构造函数的主要内容,如果未能解决你的问题,请参考以下文章
注入 dbContext 时返回“找不到与给定参数匹配的构造函数”
com.din.OSS 中构造函数的参数 0 需要找不到类型为“java.lang.String”的 bean
基类和子类函数名相同且参数类型一样,基类函数如何被覆盖,还存在吗?存在何处?请详细回答,谢谢~~~~
如何解决此问题:LoginController 中构造函数的参数 0 需要找不到类型为“OktaOAuth2Properties”的 bean