Java基础之反射

1、什么是反射

Java在运行状态中,对于任何一个类,都可以获取到这个类的属性和方法,对于任何一个对象,都能调用这个对象的方法和属性(包括私有的)。这种动态获取信息和动态调用方法的机制就叫反射。

很多人会说我直接new一个对象不就完了么,干嘛非得通过反射来获取对象。因为new属于静态编译,而反射属于动态编译。反射它只有在程序运行时它才会去获取对象,从这点上可以看出反射的强大。

要理解发射在Java中的原理,首先要知道类型信息在运行时是如何表示的。其实,这是由Class对象来完成的,它包含了所有与类有关的信息,类的属性、方法、构造器、修饰符、实现类、子类和父类等等。程序运行时,每个类都会产生一个Class对象,保存在.class文件中。所有类都是在对Class对象第一次使用时,记载到JVM中的。

这里,需要重点注意,什么是运行时?可以联想到注解。注解有三个生命周期,分别是SOURCE、CLASS和RUNTIME。其实一样的,这里RUNTIME就对标着运行时。

 2、获取Class的三种方式

方式备注
Class,forName("全限定类名")静态方法
实例对象.getClass()
类名.calss
  // 获取Class的三种方式
  Class aClass1 = Class.forName("com.teligen.backendproject.reflection.Person");
  Class aClass2 = new Person().getClass();
  Class aClass3 = Person.class;

*注意*:以上三种方式都是返回Class类型。

3、反射相关的重要的类有哪些

含义
java.lang.reflect.Class代表整个字节码,代表一个类型,代表一个类
java.lang.refelct.Constroctor代表字节码中的构造器字节码,代表类中的构造器
java.lang.Field代表字节码中的属性字节码,代表类中的成员 变量(实例变量和静态变量)
java.lang.Method代表字节码中的方法字节码,代表类中的方法
java.lang.Modify

代表字节码中的修饰符字节码,代表类中的修饰符

*注意*:要先获取到Class,才能获取到Constructor,Field,Methd...

例子,通过反射获取整个类的信息

package com.teligen.backendproject.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * @Author:
 * @Date: 2022/03/15
 */
public class ReflectionDemo {

    public static void main(String[] args) throws ClassNotFoundException {
        //获取整个类
        Class c = Class.forName("java.lang.Integer");
        //获取所有的属性?
        Field[] fs = c.getDeclaredFields();

        //定义可变长的字符串,用来存储属性
        StringBuffer sb = new StringBuffer();
        sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n");
        for(Field field:fs){
            sb.append("\t");//空格
            sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等
            sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字
            sb.append(field.getName()+";\n");//属性的名字+回车
        }
        sb.append("}");
        System.out.println(sb);
    }
}

4、思考

使用反射,在程序运行时获取类的信息,其实就是为了让我们写的代码更具有通过用性和灵活性。用深刻理解反射,就先抛弃我们日常写的业务代码,以更高的维度或者更抽象的思维去看待我们所写的“工具”。所谓工具,在单个系统叫做"Utils",在多个系统使用打成jar包叫做”组件“,组件继续发展壮大就叫”框架“。

一个好用的”工具“是需要兼容各种情况的,你肯定不知道使用该”工具“的用户传入的是什么对象,但你需要帮它得到需要的结果。

例如SpringMVC你在方法上写上对象,传入的参数就会帮你封装到对象上;Mybaties可以让我们只写接口,不写实现类,也能执行SQL;在类上家伙是那个@Component注解,Spring就会帮你创建对象。。。这些通通都有反射的身影:约定大于配置,配置大于编码。

通过”约定“的姿势,使用反射在程序运行时获取相应类的信息(毕竟作为一个”工具“,真不知道你到底传入的是什么对象),实现代码功能的通用性和灵活性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值