Java 反射

1585364631
2023-02-20 / 0 评论 / 121 阅读 / 正在检测是否收录...

Java 反射

反射(Reflection)

  • 反射就是:加载类,并且允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)。

获取类的信息并且操作类

  • 1.反射第一步:加载类,获取类的字节码:Class对象
  • 2.获取类的构造器:Constructor对象
  • 3.获取类的成员变量:Field对象
  • 4.获取类的成员方法:Method对象

获取Class对象的三种方式

  • Class c1 = 类名.class
  • 调用Class提供方法:public static Class forName(String package);
  • Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
  public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Object.class;
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());
        Class c2 = Class.forName("java.lang.Object");
        System.out.println(c1==c2);
        Object obj = new Object();
        Class c3 = obj.getClass();
        System.out.println(c3 == c2);
    }

运行结果

java.lang.Object
Object
true
true

定义Students类

  class Student{
    private String name;
    private int age;
    public int publicName;

    public Student(){
        System.out.println("无参构造");
    }
    public Student(int a){
        System.out.println("有参构造");
    }
    Student(int a,int b){
        System.out.println("default修饰有参构造");
    }
    private Student(int a, int b, int c){
        System.out.println("private修饰有参构造");
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private void run(){
        System.out.println("私密方法运行");
    }
}

获取类的构造器


public class Reflection {
    public static void getAll(){
        // 1.反射第一步:必须得到这个类的Class对象
        Class<Student> c = Student.class;
        // 2.获取类的全部构造器
        // getConstructors只能获取public修饰的全部构造器
        // Constructor[] constructors = c.getConstructors();
        // getDeclaredConstructors可以获取所有存在的构造器
        Constructor[] constructors = c.getDeclaredConstructors();
        // 3.遍历数组中的每个构造器对象
        for (Constructor constructor : constructors){
            System.out.println(constructor.getName() + "---->" + constructor.getParameterCount());
        }
    }

    public static void getOne() throws Exception {
        // 1.反射第一步:必须得到这个类的Class对象
        Class c = Student.class;
        // 2.获取类的某个构造器
        // getConstructor只能获取public修饰的单个构造器
        // Constructor<Student> constructor = c.getConstructor();
        // getDeclaredConstructor可以单个存在的构造器
        Constructor constructor = c.getDeclaredConstructor();
        System.out.println(constructor.getName() + "---->" + constructor.getParameterCount());

        // 3.获取有参数构造器
        Constructor constructor1 = c.getDeclaredConstructor(int.class);
        System.out.println(constructor1.getName() + "---->" + constructor1.getParameterCount());
    }

    public static void main(String[] args) throws Exception {
        getAll();
        System.out.println("----------------------");
        getOne();
    }

}

运行结果

study.Student---->3
study.Student---->2
study.Student---->1
study.Student---->0 
----------------------
study.Student---->0
study.Student---->1

类构造器的作用

  • setAccessible(true)禁止检查访问控制(可以破坏封装性)
  • newInstance()执行构造器的方法
  public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class c = Student.class;
        Constructor constructor =  c.getDeclaredConstructor();
        constructor.newInstance();
        Constructor constructor1 = c.getDeclaredConstructor(int.class,int.class,int.class);
        constructor1.setAccessible(true);
        constructor1.newInstance(1,2,3);
    }

运行结果

无参构造
private修饰有参构造

获取类的成员变量

  • setAccessible(true)禁止检查访问控制(可以破坏封装性)
  • set 赋值
  • get 取值
  public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        // 1.反射第一步:必须是先得到类的Class对象
        Class studentClass = Student.class;
        System.out.println(studentClass.getName());
        System.out.println("------------------------");
        // 2.获取类的全部成员变量
        // getFields获取类的全部public修饰的成员变量
        Field[] publicFields = studentClass.getFields();
        for (Field field : publicFields){
            System.out.println("public成员变量:" + field.getName() + "--->" + field.getType());
        }
        System.out.println("------------------------");
        // getDeclaredFields获取类的全部存在成员变量
        Field[] Fields = studentClass.getDeclaredFields();
        for (Field field : Fields){
            System.out.println("所有成员变量:" + field.getName() + "--->" + field.getType());
        }
        System.out.println("------------------------");
        // 3.定位某个成员变量
        {
            Field field = studentClass.getDeclaredField("name");
            System.out.println("所有成员变量:" + field.getName() + "--->" + field.getType());
            System.out.println("------------------------");
            // 赋值
            Student student = new Student();
            field.setAccessible(true); // 禁止访问控制权限
            field.set(student,"暴力赋值");
            System.out.println(student.getName());
            System.out.println("------------------------");
            //取值
            String name = (String) field.get(student);
            System.out.println(name);
        }
    }

运行结果

------------------------
public成员变量:publicName--->int
------------------------
所有成员变量:name--->class java.lang.String
所有成员变量:age--->int
所有成员变量:publicName--->int
------------------------
所有成员变量:name--->class java.lang.String
------------------------
无参构造
暴力赋值
------------------------
暴力赋值

获取类的成员方法

  • setAccessible(true)禁止检查访问控制(可以破坏封装性)
  • invoke(),执行方法,括号内必须传入类的对象
  public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class c = Student.class;
        // getMethods获取所有public修饰的成员方法
        Method[] publicMethods = c.getMethods();
        // getDeclaredMethods获取所有存在的成员方法
        Method[] methods = c.getDeclaredMethods();

        for (Method method : methods) {
            System.out.println(method.getName() + "----" + method.getParameterCount() + "----" + method.getReturnType());
        }

        System.out.println("-------------------------");

        Student student = new Student();

        Method run = c.getDeclaredMethod("run");
        run.setAccessible(true);
        run.invoke(student);

        System.out.println("-------------------------");

        Method setName = c.getDeclaredMethod("setName", String.class);

        setName.invoke(student,"方法赋值");

        Method getName = c.getDeclaredMethod("getName");

        System.out.println(getName.invoke(student));;

    }

运行结果

getName----0----class java.lang.String
run----0----void
setName----1----void
-------------------------
无参构造
私密方法运行
-------------------------
方法赋值
0

评论 (0)

取消