java反射

概念

在程序运行时动态加载一个类

  • 对于任意一个类,都能够知道这个类的属性和方法
  • 对于任意一个对象,都能够调用它的任何方法和属性

关键字:运行时、动态

补充知识点

  • 静态编译:在编译时确定类型,绑定对象
  • 动态编译:运行时确定类型,绑定对象

用途

主要用于各种框架之中

case1:JDBC

项目底层有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类

  1. 通过Class.forName()加载数据库的驱动程序 (通过反射加载,前提是引入相关了Jar包)
  2. 通过 DriverManager 类进行数据库的连接,连接的时候要输入数据库的连接地址、用户名、密码
  3. 通过Connection 接口接收连接

case2:Spring XML装配bean

  1. 将程序内所有 XML 或 Properties 配置文件加载入内存中
  2. Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息
  3. 使用反射机制,根据这个字符串获得某个类的Class实例
  4. 动态配置实例的属性

原理

预备知识:java类加载机制:https://blog.csdn.net/raichen_wang/article/details/95916851

JAVA语言编译之后会生成一个.class文件,反射就是通过字节码文件找到某一个类、类中的方法以及属性等。

反射的实现主要借助以下四个类:

  • Class:类的对象
  • Constructor:类的构造方法
  • Field:类中的属性对象
  • Method:类中的方法对象

使用

测试用例

@Data
@Builder
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }

    public Student(String name) {
        this.name = name;
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    private void showArg(String arg){
        System.out.println(arg);
    }

    public void showArg1(String arg){
        System.out.println(arg);
    }
}

获取Class对象

        Student student = Student.builder().name("BaLeMengGan").age(22).build();
        // 方式一
        Class clazz1 = Student.class;
        // 方式二
        Class clazz2 = student.getClass();
        // 方式三
        try {
            Class clazz3 = Class.forName("compare.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

获取构造方法

获取批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)   
获取单个的方法
public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
调用构造方法:
Constructor-->newInstance(Object... initargs)

        // 所有的构造方法(包括:私有、受保护、默认、公有)
        for (Constructor con : clazz1.getDeclaredConstructors()) {
            System.out.println(con);
        }
        
        // 调用构造方法
        try {
            Constructor con1 = clazz1.getConstructor(String.class);
            Object s1 = con1.newInstance("wang");
            System.out.println(s1);
        } catch (Exception e) {
            e.printStackTrace();
        }

获取成员变量

        // 获取成员变量(包括私有、受保护、默认的)
        for (Field field : clazz1.getDeclaredFields()) {
            System.out.println(field);
        }
        Student s1=new Student();
        try {
            Field f1 = clazz1.getDeclaredField("name");
            // 解除私有限定
            f1.setAccessible(true);
            f1.set(s1,"zhang");
            System.out.println(s1);
        } catch (Exception e) {
            e.printStackTrace();
        }

获取成员方法

        // 获取成员方法
        for (Method method : clazz1.getDeclaredMethods()) {
            System.out.println(method);
        }
        try {
            // 获取一个成员方法,既要传入方法名,又要传入参数类型(因为有重载)
            Method m1 = clazz1.getDeclaredMethod("showArg", String.class);
            m1.setAccessible(true);
            m1.invoke(s1, "haha");
        } catch (Exception e) {
            e.printStackTrace();
        }

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值