当前位置: 首页 > news >正文

java记录-反射

什么是反射

反射是一种让Java拥有一定动态性的机制,它允许程序在执行期间取得任何类的内部信息,并且直接操作任意对象的内部属性及方法

类加载

类加载后通过堆内存方法区的Class类型对象就能了解该类的结构信息,这个对象就像该类的一面镜子,通过这面镜子能够看到类的所有结构(无论是不是private的),所以称之为反射

某类需要被使用时,如果还未加载,系统会通过类的加载、类的连接和类的初始化三步来准备类,统称为类加载或类初始化

1. 加载:将class文件读入内存,创建一个java.lang.Class对象(任何类被使用时都会有)
2. 连接:验证内部结构,为类变量分配内存并赋默认值,将二进制数据的符号引用转为直接引用
3. 初始化:对类变量初始化(从祖宗类开始),如果类有初始化语句就依次执行

反射能做什么

在运行时

  • 判断对象的类
  • 构造任一类的对象
  • 判断任一类的成员变量和方法
  • 获取泛型信息
  • 调用任一对象的成员变量和方法
  • 处理注解
  • 动态代理

它可以动态创建对象和编译,但是反射实时给JVM需求会比直接操作慢

反射获取Class对象

Class.forName()方法通过反射直接获取test包下Dog类的Class对象

Class cls = Class.forName("test.Dog");

object.getClass()方法通过反射借助Dog类实例获取Dog类的Class对象

Class cls2 = (new Dog()).getClass();

用类名.class int[ ]也算

Class cls3 = Dog.class;

通过反射获得类的结构

调用缺省构造函数,返回Class对象的一个实例

Object istc = cls.newInstance();

获得该Class对象的实体(类,接口,数组类,void)名称

String name = cls.getName();

获得父类Class对象

Class<?> clsParent = cls.getSuperClass();

获得接口Class对象的数组

Class<?>[] Its = cls.getInterfaces();

获得该类的类加载器

ClassLoader cld = cls.getClassLoader();

获得该类Constructor对象的数组

Constructor[] constructors = cls.getConstructors();

获得一个Method对象,此对象形参为paramType

Method m = cls.getMethod(.......)

获得所有的Field属性/方法/构造器数组

Field[] fields = cls.getDeclaredFields();
Method[] methods = cls.getDeclaredMethods();
Constructor[] constructors = cls.getDeclaredConstructors();

获取public的属性/方法/构造器

Field[] fields = cls.getFields();
Method[] methods = cls.getMethods();
Constructor[] constructors = cls.getConstructors();

获取指定属性/方法/构造器

Field = cls.getField("name");
Method method1 = cls.getMethod("getName", null);
Method method2 = cls.getMethod("setName", String.class);
Constructor constructor = cls.getConstructor(String.class, int.class);//参数类型

类加载器(了解)

负责将.class文件加载入内存,并生成对应java.lang.Class对象
加载器机制:

  • 全盘负责:加载某个类时其关联的其他Class也由同一加载器加载
  • 父类委托:先让父类加载器加载,如果无法加载才自己加载
  • 缓存机制:缓存被加载过的Class,先找缓存,找不到再加载类二进制数据转换成Class对象并缓存

加载器类型:

  1. Bootstrap根类加载器,jvm内置加载器,不属于ClassLoader谱系,底层是C++,对开发者透明
  2. Plantform class loader平台类加载器,负责Java SE API的实现类和JDK特定运行时类
  3. System class loader应用程序类加载器,如果没有特别指定,则用户自定义的类加载器都以此类加载器作为父加载器。

类加载器流程

  1. 检测此Class是否载入过,即在缓冲区中是否有此Class,如果有直接进入第8步,否则进入第2步。
  2. 如果没有父类加载器,则要么Parent是根类加载器,要么本身就是根类加载器,则跳到第4步,如果父类加载器存在,则进入第3步。
  3. 请求使用父类加载器去载入目标类,如果载入成功则跳至第8步,否则接着执行第5步。
  4. 请求使用根类加载器去载入目标类,如果载入成功则跳至第8步,否则跳至第7步。
  5. 当前类加载器尝试寻找Class文件,如果找到则执行第6步,如果找不到则执行第7步。
  6. 从文件中载入Class,成功后跳至第8步。
  7. 抛出ClassNotFountException异常。
  8. 返回对应的java.lang.Class对象。

获取泛型

获取注解

看文档

http://www.lryc.cn/news/66479.html

相关文章:

  • 这次彻底不需要账号了,无需魔法永久白嫖GPT
  • 远程桌面连接是什么?如何开启远程桌面连接详细教程
  • lua实战(2)
  • UI自动化测试案例——简单的Google搜索测试
  • C++之虚函数原理
  • Windows Information Protection(WIP)部署方案
  • 细说Hibernate的缓存机制
  • 初识C++之线程库
  • ChatGLM-LLaMA-chinese-insturct 学习记录(含LoRA的源码理解)
  • JuiceFS-K8s部署
  • 2023最新版本Camtasia电脑录屏软件好不好用?
  • 第三章 Linux 初步
  • linux环境安装使用mysql详解
  • SUNTANS模型学习(9)——学习Tidal forcing算例
  • ​力扣解法汇总1010. 总持续时间可被 60 整除的歌曲
  • 利用老毛桃pe启动U盘启动ubuntu.iso,完成ubuntu系统的安装
  • 分享2个教学视频录制的方法!
  • 「SQL面试题库」 No_63 报告的记录 II
  • 【事务】怎么去理解事务?
  • camunda流程变量如何使用
  • CMIP6:WRF模式动力降尺度、单点降尺度、统计方法区域降尺度
  • 2023建筑设计师们有哪些好用的AI设计工具?
  • mysql主从复制与读写分离
  • 技术控,看这里,一款支持断点调试的数据科学工具
  • 论文导读 | 大语言模型上的精调策略
  • 进阶自动化测试,这3点你一定要知道的...
  • 网络编程套接字API
  • 数字藏品的价值和意义
  • Unity物理系统脚本编程(上)
  • Java基础(十七)File类与IO流