Java反射的原理及简单运用

1. 什么是反射

​ JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

.java文件经过虚拟机编译成.class文件,也叫字节码文件。

Java在将.class字节码文件载入时,JVM将产生一个java.lang.Class对象代表该.class字节码文件,从该Class对象中可以获得类的许多基本信息,这就是反射机制。

反射就是类在运行期间,把类中成员抽取为其它类的过程。

反射的机制如下图所示:

在这里插入图片描述

Student.java经过了jdk的哪些过程?

Student.java-----javac-----Student.class(字节码文件)-----java命令-----可执行文件

其中,类加载器ClassLoader加载字节码文件到内存中,加载完毕后,在JVM中以Class的形式存在

2. 为什么使用反射

反射是为了解决在运行期,对某个实例一无所知的情况下,如何调用其方法或属性。

例: spring框架中只需要传入类的路径----spring框架就会帮你创建类的对象。

3. 获取Class反射类的方式

获取class反射类有三种方式:

第一种:通过类名.class属性

// 第一种:通过类名.class属性获取反射类
        Class<Student> class1 = Student.class;

第二种:通过类路径获取

// 第二种:通过类路径获取
        Class class2 = Class.forName("com.fwx.entity.Student");

第三种:通过对象名获取反射类型

// 第三种:通过对象名获取反射类型
        Student student = new Student();
        Class class3 = student.getClass();

4. Class类中常用的方法

1.根据反射类得到实例对象 newInstance()

// 通过反射类创建类对象
        Student student = class1.newInstance();

2.得到反射类上的注解对象。getAnnotation()

// 获取Student类上的注解
        MyAnnotation annotation = class1.getAnnotation(MyAnnotation.class);

5. 获取Method方法类对象

获取Method方法类对象的方式有四种:

getDeclaredMethods(): 获取本类中所有的方法。

// 第一种:获取本类种所有的方法
        Method[] declaredMethods = class1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

getDeclaredMethod(“方法名”,参数类型):获取本类中指定的方法对象。

// 第二种:获取本类中指定的方法
        Method studentShow01 = class1.getDeclaredMethod("studentShow01");
        System.out.println(studentShow01);

getMethods():获取本类以及父辈类中public修饰的方法。

// 第三种:获取本类以及父类中的所有的public方法
        Method[] methods = class1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

getMethod(“方法名”,参数类型):获取本类以及父辈类中指定public修饰的方法。

// 第四种:获取本类以及父类中指定的public方法
        Method studentShow02 = class1.getMethod("schoolShow01");

6. Method类对象中常用的方法

Object r=invoke(Object对象,参数值) 调用类中的方法

		Student student = class1.newInstance();
        Method printAge = class1.getDeclaredMethod("printAge", Integer.class);
        // 调用获取的方法,传入相应的参数,返回方法返回的数据
        Object invoke = printAge.invoke(student, 20);

setAccessible()设置允许访问私有成员

		Method printAge02 = class1.getDeclaredMethod("printAge02", Integer.class);
        printAge02.setAccessible(true); // 设置允许访问私有成员
        Object invoke1 = printAge02.invoke(student, 18);

7. 获取Field属性对象的方式

获取Field属性对象的方式有四种,类似于获取Method方法类对象的方式:

getDeclaredFields(): 获取本类中所有的属性。

// 获取本类中所有的属性
        Field[] declaredFields = class1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

getDeclaredField(“属性名”):获取本类中指定的属性。

 // 获取本类中指定的属性
        Field name = class1.getDeclaredField("name");
        System.out.println(name);

getFields():获取本类以及父辈类中public修饰的属性。

// 获取本类以及父辈类中public修饰的属性
        Field[] fields = class1.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

getField(“属性名”):获取本类以及父辈类中指定public修饰的属性。

// 获取本类以及父辈类中指定public修饰的属性
        Field name1 = class1.getField("name");

8. Field类中常用的方法

set(Object对象,值):为属性赋值

// 通过类名.class属性获取反射类
        Class<Student> class1 = Student.class;
        Student student = class1.newInstance();
        // 获取本类中指定的属性
        Field name = class1.getDeclaredField("name");
        name.setAccessible(true);
        // 为属性赋值
        name.set(student,"yzf");

getName():获取属性名

getAnnotation():获取属性上的注解对象

// 获取本类中所有的属性
        Field[] declaredFields = class1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 获取属性名
            String name1 = declaredField.getName();

            // 获取属性上的注解对象
            MyAnnotation annotation = declaredField.getAnnotation(MyAnnotation.class);
            String value = annotation.value();

9. 通过读取properties属性文件,进行创建反射类,并进行相关操作

public static void main(String[] args)  throws Exception{
        // 加载数据文件
        InputStream inputStream = ReflectionTest07.class.getClassLoader().getResourceAsStream("properties.properties");
        Properties properties = new Properties();
        properties.load(inputStream);
        // 属性类读取属性文件中的key值
        String className = properties.getProperty("ClassName");
        // 根据类路径得到反射路径
        Class<?> aClass = Class.forName(className);
        // 根据反射路径得到反射对象
        Object o = aClass.newInstance();
        // 根据反射类创建类对象
        Class<?> aClass1 = o.getClass();
        // 获取对象中的所有属性
        Field[] declaredFields = aClass1.getDeclaredFields();
        // 遍历属性,进行相关操作
        for (Field declaredField : declaredFields) {
            // 相关操作代码
            System.out.println(declaredField.getName());
        }
    }

可以得知,反射是在运行时,对原来类一无所知的情况下执行

  • 28
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值