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(); } } }