|
Spec-Zone .ru
спецификации, руководства, описания, API
|
A constructor declaration includes the name, modifiers, parameters, and list of throwable exceptions. The
java.lang.reflect.Constructor class provides a way to obtain this information.
The
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;
}
}
}
// production code should handle this exception more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
}
}
}
Method.getGenericParameterTypes() will consult the
Signature Attribute in the class file if it's present. If the attribute isn't available, it falls back on
which was not changed by the introduction of generics. The other methods with name getGenericFoo() for some value of Foo in reflection are implemented similarly. The syntax for the returned values of Method.get*Types() is described in
.
Here is the output for all constructors in which have a argument.
$ 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
GenericParameterType[0]: class java.io.OutputStream
GenericParameterType[1]: class java.lang.String
*GenericParameterType[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
GenericParameterType[0]: class java.lang.String
GenericParameterType[1]: class java.lang.String
*GenericParameterType[2]: class java.util.Locale
public java.util.Formatter(java.lang.Appendable,java.util.Locale)
GenericParameterType[0]: interface java.lang.Appendable
*GenericParameterType[1]: class java.util.Locale
public java.util.Formatter(java.util.Locale)
*GenericParameterType[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
GenericParameterType[0]: class java.io.File
GenericParameterType[1]: class java.lang.String
*GenericParameterType[2]: class java.util.Locale
The next example output illustrates how to search for a parameter of type char[] in
.
$ java ConstructorSift java.lang.String "[C"
java.lang.String(int,int,char[])
GenericParameterType[0]: int
GenericParameterType[1]: int
*GenericParameterType[2]: class [C
public java.lang.String(char[],int,int)
*GenericParameterType[0]: class [C
GenericParameterType[1]: int
GenericParameterType[2]: int
public java.lang.String(char[])
*GenericParameterType[0]: class [C
The syntax for expressing arrays of reference and primitive types acceptable to
is described in
. Note that the first listed constructor is package-private, not public. It is returned because the example code uses
rather than
, which returns only public constructors.
This example shows that searching for arguments of variable arity (which have a variable number of parameters) requires use of array syntax:
$ java ConstructorSift java.lang.ProcessBuilder "[Ljava.lang.String;"
public java.lang.ProcessBuilder(java.lang.String[])
*GenericParameterType[0]: class [Ljava.lang.String;
This is the actual declaration of the constructor in source code:
public ProcessBuilder(String... command)
The parameter is represented as a single-dimension array of type java.lang.String. This can be distinguished from a parameter that is explicitly an array of java.lang.String by invoking
.
The final example reports the output for a constructor which has been declared with a generic parameter type:
$ 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>
Exception types may be retrieved for constructors in a similar way as for methods. See the