接口上的getDeclaredConstructor?

时间:2016-04-12 05:07:45

标签: java reflection

Class::getDeclaredConstructorhttp://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredConstructor-java.lang.Class...-)的javadoc说:

  

返回反映指定构造函数的Constructor对象   由此Class对象表示的类或接口。 [强调我的]

由于您无法为接口声明构造函数,返回接口的“指定构造函数”意味着什么?

我在Runnable.class上尝试过并获得了NoSuchMethodException。是否存在getDeclaredConstructor可用于接口的情况?或者javadoc中的这种语言只是一个错误?或者它是否意味着除了我如何解释它之外的东西?

3 个答案:

答案 0 :(得分:9)

Class.getConstructor的调用将导致调用Class.privateGetDeclaredConstructors以检索所有已声明的构造函数。从该列表中选择匹配构造函数:

private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
    ...
    // No cached value available; request value from VM
    if (isInterface()) {
        @SuppressWarnings("unchecked")
        Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
        res = temporaryRes;
    } else {
        res = getDeclaredConstructors0(publicOnly);
    }
    ...
    return res;
}

(我删除了部分处理缓存构造函数的代码)。

因此,对于接口,构造函数列表始终为空,并且始终会抛出NoSuchMethodException

答案 1 :(得分:4)

我不认为这是javadoc中的错误。 Class对象可以表示类或接口,该语句中没有错误。

如果您正在使用反射并明确询问特定元素,则必须确保存在具有反射调用中指定标识的元素。如果您要求提供的Class中不存在特定的构造函数,您将获得NoSuchMethodException它是接口,基本类型,数组的类,void或只是一个不声明这样的构造函数的类。

上面我强调了具体这个词。例如,在返回ClassClass::getDeclaredConstructors)接口的所有构造函数的类似方法中,处理得恰当:

  

返回反映所有内容的Constructor个对象数组   由此Class对象表示的类声明的构造函数。   这些是公共的,受保护的,默认(包)访问和私有   构造函数。返回的数组中的元素未排序   没有任何特定的顺序。如果该类有默认值   构造函数,它包含在返回的数组中。 此方法返回   如果此Class对象表示一个长度为0的数组   interface,基本类型,数组类或void。

答案 2 :(得分:-1)

这是我能想到的用例:在基于反射的应用程序中,方法接收Class参数。该方法需要构造给定类的实例,因此它检查声明的构造函数。 这是一个简化的示例,它只是在四种不同的用例上打印构造函数:

  1. 调用getClass()
  2. 的类实例
  3. 调用getClass()
  4. 的接口实例
  5. 一个实际的ClassX.class
  6. 一个实际的InterfaceY.class

    public class Testctor {
    
        public static void main(String[] args) {
            new Testctor().testGetDeclCtors();
        }
    
        public void testGetDeclCtors() {
            Class1 c1 = new Class1(4);
            printClassInfo(c1.getClass());
    
            I2 i2 = c1;
            printClassInfo(i2.getClass());
    
            printClassInfo(Class1.class);
    
            printClassInfo(I2.class);
        }
    
        private void printClassInfo(Class<?> claz) {
            Constructor<?> ctor = null;
            try {
                ctor = claz.getDeclaredConstructor();
            } catch (NoSuchMethodException | SecurityException e) {
            }
            System.out.println(claz+": "+ctor);
        }
    }
    
    interface I2 {
    }
    
    class Class1 implements I2 {
        public Class1() {
        }
    
        public Class1(int x) {
        }
    }
    
  7. 这会打印这些结果:

    class test.Class1: public test.Class1()
    class test.Class1: public test.Class1()
    class test.Class1: public test.Class1()
    interface test.I2: null