如何使用Java反射创建一个具有接受接口的构造函数的实例?

时间:2013-12-06 16:32:22

标签: java

我有下面的方法,可以帮助我创建一个类的实例,其构造函数接受一个参数。问题是我正在尝试创建一个类的实例,其构造函数将接口作为参数。当我调用下面的方法时,arg.getClass解析为派生类而不是接口,因此c.getConstructor失败并返回NoSuchMethodException。是否可以使用反射来创建以接口作为参数的对象实例?

public static <T> T getInstance(String className, Object arg)
{
  Class<?> c = Class.forName(className);
  Constructor<?> ctor = c.getConstructor(arg.getClass());
  return (T)ctor.newInstance(arg);
}

3 个答案:

答案 0 :(得分:1)

Apache Commons Lang提供了ConstructorUtils类,它具有getMatchingAccessibleConstructor(Class, Class[])方法,用于查找具有匹配类类型参数的可访问构造函数

示例:

public class Examples extends Object {

    public static void main(String[] args) throws Exception {
        Class<?> clazz = Examples.class;
        Constructor<?> cons = ConstructorUtils.getMatchingAccessibleConstructor(clazz, new Class[]{B.class});
        System.out.println(cons);
    }

    public Examples (A a) {}

    interface A {}
    static class B implements A {}
}

打印

public test.Examples(test.Examples$A)

您可以查看源代码并进行修改,以便找到所有构造函数,无论是否可访问。

答案 1 :(得分:0)

你可以尝试这样做,它会完成工作,但我不确定它是多么“干净”:

public static <T> T getInstance(String className, Object arg) {
  Class<?> c = Class.forName(className);
  Class<?>[] interfaces = arg.getClass().getInterfaces();
  Constructor<?> ctor = null;
  for (int i = 0; i < interfaces.length && ctor == null; i++) {
      try {
          ctor = c.getConstructor(interfaces[i]);
      } catch (NoSuchMethodException e) {  }
  }
  if (ctor != null) {
      return (T)ctor.newInstance(arg);
  } else {
      return null;
  }
}

答案 2 :(得分:0)

您的arg不能是接口,它只能是实现它的对象。因此,对arg.getClass()的调用将返回arg对象的类,而不是在调用Class.getConstructor(Class... parameterTypes)时用于匹配构造函数的接口。

鉴于此,你需要编写一个函数,在这些行中进行更宽松的匹配:

for (Constructor constructor : Class.forName(className).getDeclaredConstructors())
{
  if (constructor.getParameterTypes().length == 1 && constructor.getParameterTypes()[0].isAssignableFrom(arg.getClass())
  {
    return (T)constructor.newInstance(arg);
  }
}