Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并可能使用不再可用的技术。
请参阅Java语言更改,了解Java SE 9及以后版本中更新的语言特性的摘要。
请参阅JDK发行说明,了解所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
构造函数声明包括名称、修饰符、参数和可抛出异常的列表。 java.lang.reflect.Constructor类提供了一种获取此信息的方式。
示例 演示了如何搜索类的声明构造函数中具有给定类型参数的构造函数。ConstructorSift
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import static java.lang.System.out;
public class ConstructorSift {
public static void main(String... args) {
try {
Class<?> cArg = Class.forName(args[1]);
Class<?> c = Class.forName(args[0]);
Constructor[] allConstructors = c.getDeclaredConstructors();
for (Constructor ctor : allConstructors) {
Class<?>[] pType = ctor.getParameterTypes();
for (int i = 0; i < pType.length; i++) {
if (pType[i].equals(cArg)) {
out.format("%s%n", ctor.toGenericString());
Type[] gpType = ctor.getGenericParameterTypes();
for (int j = 0; j < gpType.length; j++) {
char ch = (pType[j].equals(cArg) ? '*' : ' ');
out.format("%7c%s[%d]: %s%n", ch,
"GenericParameterType", j, gpType[j]);
}
break;
}
}
}
// 产品代码应更优雅地处理此异常
} catch (ClassNotFoundException x) {
x.printStackTrace();
}
}
}
Method.getGenericParameterTypes()将在类文件中查询 Signature 属性(如果存在)。如果该属性不可用,则会退回到未更改的 Method.getParameterType()。在反射中,其他以 getGenericFoo() 命名的方法的实现方式类似。返回值的语法描述在 Class.getName() 中说明。
以下是 java.util.Formatter 中所有具有 Locale 参数的构造函数的输出。
$ java ConstructorSift java.util.Formatter java.util.Locale
public
java.util.Formatter(java.io.OutputStream,java.lang.String,java.util.Locale)
throws java.io.UnsupportedEncodingException
泛型参数类型[0]: class java.io.OutputStream
泛型参数类型[1]: class java.lang.String
*泛型参数类型[2]: class java.util.Locale
public java.util.Formatter(java.lang.String,java.lang.String,java.util.Locale)
throws java.io.FileNotFoundException,java.io.UnsupportedEncodingException
泛型参数类型[0]: class java.lang.String
泛型参数类型[1]: class java.lang.String
*泛型参数类型[2]: class java.util.Locale
public java.util.Formatter(java.lang.Appendable,java.util.Locale)
泛型参数类型[0]: interface java.lang.Appendable
*泛型参数类型[1]: class java.util.Locale
public java.util.Formatter(java.util.Locale)
*泛型参数类型[0]: class java.util.Locale
public java.util.Formatter(java.io.File,java.lang.String,java.util.Locale)
throws java.io.FileNotFoundException,java.io.UnsupportedEncodingException
泛型参数类型[0]: class java.io.File
泛型参数类型[1]: class java.lang.String
*泛型参数类型[2]: class java.util.Locale
下一个示例输出演示了如何在String中搜索char[]类型的参数。
$ java ConstructorSift java.lang.String "[C"
java.lang.String(int,int,char[])
泛型参数类型[0]: int
泛型参数类型[1]: int
*泛型参数类型[2]: class [C
public java.lang.String(char[],int,int)
*泛型参数类型[0]: class [C
泛型参数类型[1]: int
泛型参数类型[2]: int
public java.lang.String(char[])
*泛型参数类型[0]: class [C
表示可接受Class.forName()的引用和基本类型数组的语法在Class.getName()中描述。请注意,第一个列出的构造函数是package-private,而不是public。它被返回是因为示例代码使用Class.getDeclaredConstructors()而不是Class.getConstructors(),后者只返回public构造函数。
此示例说明了搜索可变参数(具有可变数量参数)的参数需要使用数组语法:
$ java ConstructorSift java.lang.ProcessBuilder "[Ljava.lang.String;"
public java.lang.ProcessBuilder(java.lang.String[])
*GenericParameterType[0]: class [Ljava.lang.String;
这是源代码中ProcessBuilder构造函数的实际声明:
public ProcessBuilder(String... command)
参数被表示为java.lang.String类型的一维数组。可以通过调用Constructor.isVarArgs()来区分它与显式声明为java.lang.String数组的参数。
最后一个例子报告了使用泛型参数类型声明的构造函数的输出:
$ java ConstructorSift java.util.HashMap java.util.Map
public java.util.HashMap(java.util.Map<? extends K, ? extends V>)
*GenericParameterType[0]: java.util.Map<? extends K, ? extends V>
与方法一样,可以通过类似的方式检索构造函数的异常类型。有关详细信息,请参阅获取方法类型信息部分中描述的MethodSpy示例。