Class::getDeclaredConstructor
(http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredConstructor-java.lang.Class...-)的javadoc说:
返回反映指定构造函数的Constructor对象 由此Class对象表示的类或接口。 [强调我的]
由于您无法为接口声明构造函数,返回接口的“指定构造函数”意味着什么?
我在Runnable.class
上尝试过并获得了NoSuchMethodException
。是否存在getDeclaredConstructor
可用于接口的情况?或者javadoc中的这种语言只是一个错误?或者它是否意味着除了我如何解释它之外的东西?
答案 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或只是一个不声明这样的构造函数的类。
上面我强调了具体这个词。例如,在返回Class
(Class::getDeclaredConstructors)接口的所有构造函数的类似方法中,处理得恰当:
返回反映所有内容的
Constructor
个对象数组 由此Class
对象表示的类声明的构造函数。 这些是公共的,受保护的,默认(包)访问和私有 构造函数。返回的数组中的元素未排序 没有任何特定的顺序。如果该类有默认值 构造函数,它包含在返回的数组中。 此方法返回 如果此Class
对象表示一个长度为0的数组 interface,基本类型,数组类或void。
答案 2 :(得分:-1)
这是我能想到的用例:在基于反射的应用程序中,方法接收Class参数。该方法需要构造给定类的实例,因此它检查声明的构造函数。 这是一个简化的示例,它只是在四种不同的用例上打印构造函数:
一个实际的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) {
}
}
这会打印这些结果:
class test.Class1: public test.Class1()
class test.Class1: public test.Class1()
class test.Class1: public test.Class1()
interface test.I2: null