A constructor declaration includes the name, modifiers, parameters, and list of throwable exceptions. Thejava.lang.reflect.Constructor
class provides a way to obtain this information.The
example illustrates how to search a class's declared constructors for one which has a parameter of a given type.
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; } } } // 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 onMethod.getParameterType()
which was not changed by the introduction of generics. The other methods with namegetGenericFoo()
for some value of Foo in reflection are implemented similarly. The syntax for the returned values ofMethod.get*Types()
is described inClass.getName()
.Here is the output for all constructors in
java.util.Formatter
which have aLocale
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.LocaleThe next example output illustrates how to search for a parameter of type
char[]
inString
.$ 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 [CThe syntax for expressing arrays of reference and primitive types acceptable to
Class.forName()
is described inClass.getName()
. Note that the first listed constructor ispackage-private
, notpublic
. It is returned because the example code usesClass.getDeclaredConstructors()
rather thanClass.getConstructors()
, which returns onlypublic
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
ProcessBuilder
constructor in source code:The parameter is represented as a single-dimension array of typepublic ProcessBuilder(String... command)java.lang.String
. This can be distinguished from a parameter that is explicitly an array ofjava.lang.String
by invokingConstructor.isVarArgs()
.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
example described in Obtaining Method Type Information section for further details.
MethodSpy