1. Overview
A Constructor is used in the creation of an object that is an instance of a class. Typically it performs operations required to initialize the class before methods are invoked or fields are accessed. Constructors are never inherited.
The key classes used when working with constructors are Class and java.lang.reflect.Constructor.
The below class diagram show a list of Reflection APIs offered by java.lang.reflect.Constructor.
![]() |
Java Reflection for Constructors |
2. Reflection Constructors API Examples
- Finding Constructors
- Retrieving and Parsing Constructor Modifiers
- Creating New Class Instances
- Get Constructor
- Get Constructor Information
2.1 Finding Constructors
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 ConstructorSift example illustrates how to search a class's declared constructors for one which has a parameter of a given type.
package com.javaguides.reflection.constructors;
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("java.util.Locale");
Class<?> c = Class.forName("java.util.Formatter");
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();
}
}
}
Output:
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.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
private java.util.Formatter(java.nio.charset.Charset,java.util.Locale,java.io.File)
throws java.io.FileNotFoundException
GenericParameterType[0]: class java.nio.charset.Charset
*GenericParameterType[1]: class java.util.Locale
GenericParameterType[2]: class java.io.File
private java.util.Formatter(java.util.Locale,java.lang.Appendable)
*GenericParameterType[0]: class java.util.Locale
GenericParameterType[1]: interface java.lang.Appendable
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.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
2.2 Retrieving and Parsing Constructor Modifiers
Because of the role of constructors in the language, fewer modifiers are meaningful than for methods:
- Access modifiers: public, protected, and private
- Annotations
The ConstructorAccess example searches for constructors in a given class with the specified access modifier. It also displays whether the constructor is synthetic (compiler-generated) or of variable arity.
package com.javaguides.reflection.constructors;
import static java.lang.System.out;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class ConstructorAccess {
public static void main(String... args) {
try {
Class<?> c = Class.forName("java.io.File");
Constructor[] allConstructors = c.getDeclaredConstructors();
for (Constructor ctor : allConstructors) {
int searchMod = modifierFromString("private");
int mods = accessModifiers(ctor.getModifiers());
if (searchMod == mods) {
out.format("%s%n", ctor.toGenericString());
out.format(" [ synthetic=%-5b var_args=%-5b ]%n", ctor.isSynthetic(), ctor.isVarArgs());
}
}
// production code should handle this exception more gracefully
} catch (ClassNotFoundException x) {
x.printStackTrace();
}
}
private static int accessModifiers(int m) {
return m & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED);
}
private static int modifierFromString(String s) {
if ("public".equals(s))
return Modifier.PUBLIC;
else if ("protected".equals(s))
return Modifier.PROTECTED;
else if ("private".equals(s))
return Modifier.PRIVATE;
else if ("package-private".equals(s))
return 0;
else
return -1;
}
}
Output:
private java.io.File(java.lang.String,java.io.File)
[ synthetic=false var_args=false ]
private java.io.File(java.lang.String,int)
[ synthetic=false var_args=false ]
2.3 Creating New Class Instances
There are two reflective methods for creating instances of classes: java.lang.reflect.Constructor.newInstance() and Class.newInstance().
package com.javaguides.reflection.constructors;
import java.io.Console;
import java.nio.charset.Charset;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import static java.lang.System.out;
public class ConsoleCharset {
public static void main(String... args) {
Constructor[] ctors = Console.class.getDeclaredConstructors();
Constructor ctor = null;
for (int i = 0; i < ctors.length; i++) {
ctor = ctors[i];
if (ctor.getGenericParameterTypes().length == 0)
break;
}
try {
ctor.setAccessible(true);
Console c = (Console) ctor.newInstance();
Field f = c.getClass().getDeclaredField("cs");
f.setAccessible(true);
out.format("Console charset : %s%n", f.get(c));
out.format("Charset.defaultCharset(): %s%n", Charset.defaultCharset());
// production code should handle these exceptions more gracefully
} catch (InstantiationException x) {
x.printStackTrace();
} catch (InvocationTargetException x) {
x.printStackTrace();
} catch (IllegalAccessException x) {
x.printStackTrace();
} catch (NoSuchFieldException x) {
x.printStackTrace();
}
}
}
Output:
Console charset : windows-1252
Charset.defaultCharset(): windows-1252
Let's learn few more examples, first create Customer.java class and apply Reflection Constructor API on Customer class.
Customer.java
package com.javaguides.reflection.constructors;
public class Customer {
private int id;
private String firstName;
private String lastName;
public Customer(int id, String firstName, String lastName) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
2.4 Get Constructor
_ getConstructor()_ method on the class representation of an object to get specific public constructor.
Class<?> clazz = Class.forName("com.javaguides.reflection.constructors.Customer");
Constructor<?> constructor = clazz.getConstructor(int.class, String.class, String.class);
// getting constructor parameters
System.out.println(Arrays.toString(constructor.getParameterTypes()));
Constructor<?> hashMapConstructor = Class.forName("java.util.HashMap").getConstructor(null);
System.out.println(Arrays.toString(hashMapConstructor.getParameterTypes()));
Output:
[int, class java.lang.String, class java.lang.String]
[]
2.5 Get Constructor Information
Let's use Constructor Reflection API's to obtain Customer Constructor information.
Class<?> clazz = Class.forName("com.javaguides.reflection.constructors.Customer");
Constructor[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
// get constructor name
System.out.println(constructor.getName());
// get constructor parameters
System.out.println(Arrays.toString(constructor.getParameterTypes()));
// Get parameter count
System.out.println(constructor.getParameterCount());
System.out.println(constructor.getDeclaringClass().getCanonicalName());
}
Output:
com.javaguides.reflection.constructors.Customer
[int, class java.lang.String, class java.lang.String]
3
com.javaguides.reflection.constructors.Customer
Comments
Post a Comment
Leave Comment