Java反射–类构造函数
使用Java Reflection,我们可以获得有关类的构造函数的信息,也可以创建一个新的类实例。在Java Reflection API中,存在一个类java.lang.reflect.Constructor,该类具有用于查找构造函数,检索构造函数修饰符和创建新实例的方法。
获取构造函数实例
第一件事是获取java.lang.reflect.Constructor类的实例,我们将必须使用java.lang.Class的方法,因为该类是所有反射操作的入口点。有5种获取构造方法实例的方法
getConstructor(Class <?> ... parameterTypes)此方法返回一个Constructor对象,其中传递的参数类型与该类中构造函数的参数匹配。
getConstructors()返回一个包含构造函数对象的数组,该对象反映此Class对象表示的类的所有公共构造函数。
getDeclaredConstructor(Class <?>…parameterTypes)此方法返回一个Constructor对象,其中传递的参数类型与该类中构造函数的参数匹配。此方法与getCOnstructor()的不同之处在于,该方法还可以匹配私有或者受保护的构造函数。
getDeclaredConstructors()返回一个构造函数对象数组,该对象反映由此Class对象表示的类声明的所有构造函数。
getEnclosingConstructor()如果此Class对象表示构造函数中的本地或者匿名类,则返回一个Constructor对象,该对象表示基础类的直接封闭的构造函数。
获取有关类构造函数的信息-Java示例
此示例说明如何获取信息,例如参数类型,类的单个/所有构造函数的修饰符。
以下是用于示例的类。
public class Message {
String msg;
public Message(String msg){
this.msg = msg;
}
private Message() {
}
public void displayMessage(){
System.out.println(msg);
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;
public class ReflectionDemo {
public static void main(String[] args) {
try {
Message message = new Message("Java Reflection example");
// get instance of Class
Class<?> c = message.getClass();
System.out.println("--- getConstructor() ---");
Constructor<?> constructor = c.getConstructor(new Class[]{String.class});
System.out.println("Constructor Name- " + constructor.getName());
System.out.println("Constructor Parameters- " + Arrays.toString(constructor.getParameterTypes()));
System.out.println("Constructor Modifier- " + Modifier.toString(constructor.getModifiers()));
System.out.println("--- getDeclaredConstructor() ---");
constructor = c.getDeclaredConstructor();
System.out.println("Constructor Name- " + constructor.getName());
System.out.println("Constructor Parameters- " + Arrays.toString(constructor.getParameterTypes()));
System.out.println("Constructor Modifier- " + Modifier.toString(constructor.getModifiers()));
System.out.println("--- getConstructors() ---");
Constructor<?>[] cons = c.getConstructors();
System.out.println("Constructor Name- " + Arrays.toString(cons));
System.out.println("--- getDeclaredConstructors() ---");
cons = c.getDeclaredConstructors();
for(Constructor<?> ct : cons) {
System.out.println("Constructor Name- " + ct.getName());
System.out.println("Constructor Parameters- " + Arrays.toString(ct.getParameterTypes()));
System.out.println("Constructor Modifier- " + Modifier.toString(ct.getModifiers()));
}
} catch (NoSuchMethodException | IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出:
--- getConstructor() -- Constructor Name- com.theitroad.programs.Message Constructor Parameters- [class java.lang.String] Constructor Modifier- public --- getDeclaredConstructor() -- Constructor Name- com.theitroad.programs.Message Constructor Parameters- [] Constructor Modifier- private --- getConstructors() -- Constructor Name- [public com.theitroad.programs.Message(java.lang.String)] --- getDeclaredConstructors() -- Constructor Name- com.theitroad.programs.Message Constructor Parameters- [class java.lang.String] Constructor Modifier- public Constructor Name- com.theitroad.programs.Message Constructor Parameters- [] Constructor Modifier- private
使用Java Reflection获取新的类实例
在Java中,有两种用于创建类实例的反射方法:java.lang.reflect.Constructor.newInstance()和Class.newInstance()。在这里,我们将看到一个使用Java Reflection API的Constructor类创建类实例的示例,这也是Java docshttps://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html的首选方式
newInstance(Object…initargs)使用此Constructor对象表示的构造函数,以指定的初始化参数创建和初始化构造函数的声明类的新实例。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectionDemo {
public static void main(String[] args) {
try {
Message message = new Message("Java Reflection example");
// get instance of Class
Class<?> c = message.getClass();
Constructor<?> constructor = c.getConstructor(new Class[]{String.class});
Message m = (Message)constructor.newInstance("Hello");
m.displayMessage();
} catch (NoSuchMethodException | IllegalArgumentException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
使用私有构造函数获取新的类实例
我们也可以通过使用类的私有构造函数来获取新的类实例。
一旦有了Constructor对象,就必须使用从类java.lang.reflect.AccessibleObject继承的setAccessible()方法将其访问权限设置为true。
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ReflectionDemo {
public static void main(String[] args) {
try {
Message message = new Message("Java Reflection example");
// get instance of Class
Class<?> c = message.getClass();
// Getting private constructor
Constructor<?> constructor = c.getDeclaredConstructor();
constructor.setAccessible(true);
Message m = (Message)constructor.newInstance();
m.displayMessage();
} catch (NoSuchMethodException | IllegalArgumentException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

