Java反射

一、Java反射概念

在 Java 中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法,并且对于任意一个对象,都能够调用它的任意一个方法。
这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制,很多优秀的开源框架都是通过反射完成的。

二、Java 反射 API

反射 API 用来生成 JVM 中的类、接口或则对象的信息。
Class 类:反射的核心类,可以获取类的属性,方法等信息。
Field 类:Java.lang.reflec 包中的类,表示类的成员变量,可以用来获取和设置类之中的属性
Method 类: Java.lang.reflec 包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法。
Constructor 类: Java.lang.reflec 包中的类,表示类的构造方法。

2.1 获取 Class 对象的 3 种方法

  1. 调用某个对象的 getClass()方法
Person p=new Person();
Class clazz=p.getClass();
  1. 调用某个类的 class 属性来获取该类对应的 Class 对象
Class clazz=Person.class;
  1. 使用 Class 类中的 forName()静态方法(最安全/性能最好)
Class clazz=Class.forName("类的全路径"); (最常用)

当我们获得了想要操作的类的 Class 对象后,可以通过 Class 类中的方法获取并查看该类中的方法属性

//当我们获得了想要操作的类的 Class 对象后,可以通过 Class 类中的方法获取并查看该类中的方法和属性。
        //获取类的所有方法信息
        Method[] methods = aClass3.getMethods();
        for (Method method : methods) {
            System.out.println("方法:"+method.getName()+"()");
        }

//        Method[] declaredMethods = aClass3.getDeclaredMethods();
//        for (Method declaredMethod : declaredMethods) {
//            System.out.println("声明的方法"+declaredMethod.toString());
//        }

        /**
         *getFields() 获得某个类的所有的公共(public)的字段,包括父类中的字段。
         *getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
         */
        Field[] fields = aClass3.getFields();
        for (Field field : fields) {
            System.out.println("private字段:"+field.toString());
        }
        Field[] declaredFields = aClass3.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("类中所有声明的字段:"+declaredField);

        }

        Constructor<?>[] constructors = aClass3.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("构造函数:"+constructor.toString());
        }

2.2 通过class对象创建对象实例

  1. 使用Class 对象的 newInstance()方法;
  2. 调用 Constructor 对象的 newInstance()
 		//通过Class对象的newInstance方法创造实例对象
        Student stu1 = (Student)aClass3.newInstance();
        System.out.println(stu1);

        //首先通过class对象获得一个构造方法,在通过构造方法创建实例对象
        Constructor<?> constructor = aClass3.getConstructor(String.class,int.class);
        Student stu2 = (Student)constructor.newInstance("北京大学",703);
        System.out.println(stu2);

三、代码演示

@Data
public class Person {
    private String name;
    private String sex;
    private Integer age;
}

@Data
public class Student extends Person {
    private String schoolName;
    private Integer score;
    public String teacher;


    public Student(){
        System.out.println("Student无参构造");
    }
    public Student(String schoolName,int score){
        this.schoolName = schoolName;
        this.score = score;
        System.out.println("Student有参构造");
    }
}

完整代码

package com.lsh.reflectbylsh;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author :LiuShihao
 * @date :Created in 2021/2/25 7:38 下午
 * @desc : 学习Java反射机制
 */
public class ReflectDemo {
    /**
     * 获得class对象的三种形式:
     * 1.调用某个对象的 getClass()方法
     * 2.调用某个类的 class 属性来获取该类对应的 Class 对象
     * 3.使用 Class 类中的 forName()静态方法(最安全/性能最好)
     */
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Student student = new Student();
        Class<? extends Student> aClass1 = student.getClass();

        Class<Student> aClass2 = Student.class;

        Class<?> aClass3 = Class.forName("com.lsh.reflectbylsh.Student");


        //当我们获得了想要操作的类的 Class 对象后,可以通过 Class 类中的方法获取并查看该类中的方法和属性。
        //获取类的所有方法信息
        Method[] methods = aClass3.getMethods();
        for (Method method : methods) {
            System.out.println("方法:"+method.getName()+"()");
        }

//        Method[] declaredMethods = aClass3.getDeclaredMethods();
//        for (Method declaredMethod : declaredMethods) {
//            System.out.println("声明的方法"+declaredMethod.toString());
//        }

        /**
         *getFields() 获得某个类的所有的公共(public)的字段,包括父类中的字段。
         * getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
         */
        Field[] fields = aClass3.getFields();
        for (Field field : fields) {
            System.out.println("private字段:"+field.toString());
        }
        Field[] declaredFields = aClass3.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("类中所有声明的字段:"+declaredField);

        }

        Constructor<?>[] constructors = aClass3.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("构造函数:"+constructor.toString());
        }
        //通过Class对象的newInstance方法创造实例对象
        Student stu1 = (Student)aClass3.newInstance();
        System.out.println(stu1);

        //首先通过class对象获得一个构造方法,在通过构造方法创建实例对象
        Constructor<?> constructor = aClass3.getConstructor(String.class,int.class);
        Student stu2 = (Student)constructor.newInstance("北京大学",703);
        System.out.println(stu2);

    }


}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liu_Shihao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值