Java反射–类构造函数

时间:2020-01-09 10:35:19  来源:igfitidea点击:

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