Java面试基础篇之反射

什么是反射?

  • 反射是一种动态机制,让我们可以在程序运行时动态创建对象,获取到类的信息等,可以提高程序的灵活度,反射在框架中被大量运用

如何使用反射?

想要使用反射必须先获得一个类的字节码对象,也叫类对象(Class对象),JVM在加载类时,会把.class文件读取至内存, 生成一个Class对象,由于双亲委派机制的存在,一个类的Class对象在内存中只有一个

  • 首先准备一个Student
package reflect;

public class Student {
    public Integer age;
    private String name;

    public Student(){
        System.out.println("无参构造方法正在执行..");
    }

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

    public void sayHello(){
        System.out.println("Student.sayHello()正在执行..");
    }

    public void sayHello(String name){
        System.out.println("Student.sayHello()正在执行..传入的参数是: " + name);
    }

    private void privateMethod(){
        System.out.println("Student.privateMethod()私有方法正在执行..");
    }
}
  • 获取类的Class对象
package reflect;

public class ReflectDemo1 {
    public static void main(String[] args) {
        // 第一种获取Class对象的方式
        Student student = new Student(); // 实例化Student
        Class stuClass1 = student.getClass();// 获取Class对象
        System.out.println(stuClass1.getName());// 打印Class对象的全限定名

        // 第二种获取Class对象的方式
        Class stuClass2 = Student.class; // 获取Class对象
        System.out.println(stuClass1 == stuClass2); // 比较两个是否是一个对象true

        // 第三种获取Class对象的方式
        try {
            Class stuClass3 = Class.forName("reflect.Student");// 填入类的全限定名,需要捕获或抛出异常
            System.out.println(stuClass2 == stuClass3);// 比较两个是否是一个对象true
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
  • 调用构造方法来实例化对象
package reflect;

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

public class ReflectDemo2 {
    public static void main(String[] args) {
        try {
            // 动态调用Student的无参构造方法
            Class stuClass = Class.forName("reflect.Student");// 获取Class对象
            stuClass.newInstance(); // 实例化对象

            // 动态调用Student的有参构造方法
            Constructor constructor = stuClass.getConstructor(String.class,Integer.class); // 指定构造器的参数数据类型
            Object obj = constructor.newInstance("张三",18); // 传入参数

            // 动态获取Student的公开属性
            Field field = stuClass.getField("age");
            Integer age =(Integer) field.get(obj); // 获取属性
            System.out.println("学生的年龄为: " + age);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 获取类的信息,属性,方法等等
package reflect;

import java.lang.reflect.Method;

public class ReflectDemo3 {
    public static void main(String[] args) {
        try {
            // 动态调用类的无参方法
            Class stuClass = Class.forName("reflect.Student");// 获取Class对象
            Object obj = stuClass.newInstance(); // 实例化Student对象
            Method sayHello = stuClass.getMethod("sayHello");// 获取需要调用的方法
            sayHello.invoke(obj); // 执行方法

            // 动态调用类的有参方法
            Method setName = stuClass.getMethod("sayHello",String.class);// 需要传入发方法名和方法形参对应的数据类型
            setName.invoke(obj, "你好");// 传入参数值并执行
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 反射可以强制访问类的私有属性和方法
package reflect;

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

public class ReflectDemo4 {
    public static void main(String[] args) {
        try {
            // 动态调用类的私有属性
            Class stuClass = Class.forName("reflect.Student");
            Constructor constructor = stuClass.getConstructor(String.class, Integer.class);
            Object obj = constructor.newInstance("张三",18);
            Field field = stuClass.getDeclaredField("name"); // 可以获取类中的所有属性,包括私有属性
            field.setAccessible(true); // 暴力反射,强制开启该属性的访问权限
            System.out.println(field.get(obj));

            // 动态调用类的私有方法
            Method privateMethod = stuClass.getDeclaredMethod("privateMethod"); // 可以获取类中的所有方法,包括私有方法
            privateMethod.setAccessible(true); // 暴力反射,强制开启该方法的访问权限
            privateMethod.invoke(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 以上是反射的一些基础用法,当然反射不止于此,有兴趣可以再深入研究

反射的使用场景?

  • 反射是框架的灵魂,平时我们在实际开发中很少运用到反射机制,但是在Spring/Mybatis等框架底层,大量的用到反射技术
  • 比如Spring中的**IOC(控制反转),AOP面向切面编程**,MybatisMapper接口代理对象,JDBC连接数据库时,指定连接数据库驱动类都有用到反射
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值