【问题标题】:Java Reflection getConstructor methodJava反射getConstructor方法
【发布时间】:2012-11-10 14:48:00
【问题描述】:

假设我有课程AB,其中B 扩展A。我在B 中还有一个构造函数,其中一个参数类型为A。我还有一个 B 类型的对象,名为 bObj

有没有办法调用B.class.getConstructor(new Class[] { bObj.getClass() }) 并获取构造函数,因为B 扩展了A?目前我收到了NoSuchMethodException

【问题讨论】:

  • B.class.getConstructors()怎么样,找到只带一个参数的那个,看看A.classisAssignableFrom是不是这个?
  • arne.b 这是一种方法,但我认为它实际上可能更容易。 Nandkumar 是的,它是公开的。
  • 感谢您的建议。我想我对您提供的答案感到满意。 :)

标签: java inheritance reflection extends getconstructor


【解决方案1】:

不,搜索您的方法需要精确的参数。因此,当您使用反射 API 的查找/搜索方法查找构造函数、方法或字段时,该 API 使用equals() 来查找匹配项。

如果您需要与 Java 编译器相同的逻辑,您将需要使用像 FEST Reflectcommons beanutils 这样的框架。或者您必须调用getConstructors() 并编写您自己的过滤器代码。

乍一看,这似乎很愚蠢:如果 Java 编译器可以做到,为什么反射 API 不能呢?有两个原因:第一,Java运行时不需要搜索调用哪个方法,因为编译器已经选择了正确的方法。

第二个原因是反射 API 总是“次佳”。它可以做任何事情,但目标永远不是让它真正易于/友好地使用(至少,这是我每次使用它时的想法:-)

【讨论】:

    【解决方案2】:

    我建议你看看Apache Commons Lang中的ConstructorUtils
    他们有各种各样的构造函数发现方法。

    您的案件应由“Matching Accessible Constructors”覆盖。

    Here 是上下文中使用的方法的一个示例。 基本上,你这样称呼它:

     private <T> T instantiate(Class<?> input, Object parameter) {
      try {
        Constructor<?> constructor = ConstructorUtils.getMatchingAccessibleConstructor(input, parameter.getClass());
        return (T) constructor.newInstance(parameter);
      } catch (Exception e) {
        //handle various exceptions
      } 
    }
    

    【讨论】:

    • 这工作完美无缺,而且 - 在我看来 - 非常优雅。两个附加提示: (1) 如果将“输入”参数声明为Class&lt;T&gt; input,则可以防止强制转换返回值。 (2)ConstructorUtils.invokeConstructor(Class&lt;T&gt; cls, Object... args)结合了获取构造函数和创建新实例。
    【解决方案3】:

    如果您的构造函数不是公共的(或者如果它的类不是公共的),或者无法从您的代码范围访问,则不会通过返回

    Class.getConstructor()
    

    试试

    Class.getDeclaredConstructor()
    

    改为

    【讨论】:

      猜你喜欢
      • 2015-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多