猿问

当参数是构造函数的参数声明类型的子类时,反射找不到构造函数

我正在使用反射为特定需求实例化类。


当前代码是这样的:


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

你有什么解决方案来处理这个问题吗?


谢谢


鸿蒙传说
浏览 192回答 2
2回答

慕仙森

所述java.beans封装具有类Statement和Expression其可以执行与子类型规则的必要查找:Expression&nbsp;e&nbsp;=&nbsp;new&nbsp;Expression(Foo.class,&nbsp;"new",&nbsp;new&nbsp;Object[]{&nbsp;new&nbsp;B()&nbsp;}); Foo&nbsp;foo&nbsp;=&nbsp;(Foo)e.getValue();该execute方法的文档描述了"new"用于调用构造函数的特殊伪方法名称。

MMTTMM

我选择使用的解决方案是 apache.commons.lang.reflect 提供的方法它提供了两个不同的版本:需要完全匹配参数类型:invokeExactConstructor()一种通过赋值兼容性匹配参数类型:invokeConstructor()我已经进行了简短的测试,并且可以正常工作。所以我正在使用它。结果如下:public final <T> T instanciate(Class<? extends T> clazz, Object... args) {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; return clazz.cast(ConstructorUtils.invokeConstructor(clazz, args));&nbsp; &nbsp; } catch (Exception e) {&nbsp; &nbsp; &nbsp; &nbsp; throw new RuntimeException("Failed to instanciate Object", e);&nbsp; &nbsp; }}非常简单的代码,很好
随时随地看视频慕课网APP

相关分类

Java
我要回答