java - Class.getDeclaredConstructor 不检索兼容的参数父类(super class)型构造函数

标签 java reflection

在我的程序中,我将 JComponent 类注册到我的类中,为我的目的处理它们(将它们的值转换为设置条目)。它看起来像这样:

 InputHandlers.register(InputJTextField.class,  javax.swing.JPasswordField.class);
 InputHandlers.register(InputJTextField.class,  JTextField.class);
 InputHandlers.register(InputJCheckBox.class,  JCheckBox.class);
 ...

我将这些注册值保存到 Map 并稍后检索它们。但是对于上面的例子,我有一个问题:虽然 javax.swing.JPasswordField.classJTextField.class 的子类型,但是 Class.getDeclaredConstructor 不这么看。

我举了一个通用的例子来让这个问题更容易回答。考虑以下类(class):

  class A {
    private final B b;
    public A(B b) {
      this.b = b;
    }
  }
  class B {}
  class C extends B {}

假设您想这样做:

 A.class.getDeclaredConstructor(C.class);

即使 CB 的子类型,它也会抛出 java.lang.NoSuchMethodException。这是完整的代码:

/**
 * Test how Class.getDeclaredConstructor seeks for constructors.
 * @author Jakub
 */
public class Constructors {
  public static class A {
    private final B b;
    public A(B b) {
      this.b = b;
    }
  }
  public static class B {}
  public static class C extends B {}
  public static void main(String[] args) //throws Exception
  {
    /** TRY USING REFLECTION **/
    //Make A from B
    tryAfromParam(new B());
    //Make A from C that is cast to B
    tryAfromParam((B)new C());
    //Make A from C without casting
    tryAfromParam(new C());
  }
  public static A tryAfromParam(Object param) {
    System.out.println("Try to make A from "+param.getClass()+" using A.class.getConstructor(...)");
    try {
      A a = AfromParam(param);
      System.out.println("    Sucess :)");
      return a;
    } catch (Exception ex) {
      System.out.println("    CONSTRUCTOR FAILED: "+ex);
    }
    return null;
  }
  public static A AfromParam(Object param) throws Exception {
    //Fetch the A's class instance
    Class cls = A.class;
    //Define constructor parameters
    Class[] arguments = new Class[] {
      param.getClass()
    };
    //Try to get the constructor
    Constructor<A> c = cls.getConstructor(arguments);
    //Try to instantiate A
    A a = c.newInstance(param);
    //Return result
    return a;
  }
}

问题是:如何找到与参数或其任何父类(super class)型兼容的构造函数?请注意 new A(new C()) 是有效的,因此反射应该以相同的方式工作 - 通常我想以 Java 调用它的方式调用构造函数。

最佳答案

你可以用 java.beans.Expression: 在一行中正确地做到这一点

C c;
A a = (A)new Expression(A.class, "new", new Object[]{c}).getValue();

关于java - Class.getDeclaredConstructor 不检索兼容的参数父类(super class)型构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29312213/

相关文章:

java - 计算最终 map 中的总行数会减少hadoop中的输出

c# - 在不同的 AppDomain 中加载/卸载程序集

java - 直接或在继承接口(interface)中注释的切入点匹配方法?

java - rxjava2 中的运算符延迟

java - android - 如何获取网络源代码? (空异常)

java - 无法在 hibernate 和 spring mvc 中添加或更新外键

java - Netbeans 查找 : defining ServiceProvider with annotations and not via text/xml files

java - 直接获取字段的注解

golang递归反射

scala - 通过反射获取案例类的参数