一 反射概述
1 反射概述
什么是反射?
反射能做什么?
反射的应用场景?
类加载器ClassLoader
Class对象
类的加载机制
Class对象
2 反射方式获取构造方法并使用
Constructor对象
通过Class对象获取构造器对象
Constructor的常用方法
3 反射方式获取成员方法并使用
Method对象
通过Class对象获取方法
Method的常用方法
4 反射方式获取成员变量并使用
Field对象
通过Class对象获取属性
Field的常用方法
二 反射
1 反射概述
1.1 什么是反射?
A 概念
程序在运行中分析类的一种能力.
在程序运行期间, 根据类的字节码对象获取类的成员并使用的一项技术.
B 普通的程序运行流程:
首先在*.java为后缀名的源文件中编写源代码,
之后通过编译, 编译成*.class为后缀名的字节码文件,
类加载器负责把*.class文件加载到内存中, 并生成Class对象
我们就可以通过obj.method()形式来调用具体的方法.
将这一过程反过来, 就可以理解为反射.
C JVM基本原理
在*.java为后缀名的源文件中编写源代码,
之后通过编译, 编译成*.class为后缀名的字节码文件,
Java虚拟机(JVM)上读取并处理*.class文件,
最主要是类的加载: 把类的.class文件中的二进制数据读入到内存中,
将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class对象,用来封装类在方法区内的数据结构
Java解释器负责将JVM的代码在特定的平台上运行.(在不同的操作系统安装符合其类型的JVM运行程序)
1.2 反射能做什么?
分析类
加载并初始化一个类
查看类的所有属性和方法
查看并使用对象
查看一个对象的所有属性和方法
使用对象的任意属性和方法
1.3 反射的应用场景?
反射技术致力于构建通用的底层代码,让所有的模块调用,提高程序的扩展性。
构建通用的工具
搭建具有高度灵活性和扩展性的系统框架
2 反射有关的类
2.1 Class对象
A 对应关系
一个*.java源文件对应一个*.class的字节码文件, 一个字节码文件对应一个Class对象
B 获取Class对象的三种方式 == 实例化Class类对象
Object类的getClass()方法
类的静态属性
Class类的静态方法
Class clazz = 对象名.getClass();
Class clazz = 类名.class;
Class clazz = Class.forName(“类的正名”); // 正名:包类路径名
C 为什么创建类的实例时, 通常采用forName()方法?
因为forName()方法g更具灵活性.
对象名.getClass()和 类名.class, 都需要导入一个明确的类.
如果一个类操作不明确时, 使用起来会受限制.
而forName()方法只要以字符串方式传入即可.
2.2 类加载器 ClassLoader
A 类的加载机制
系统通过加载、连接、初始化三个步骤对类进行初始化
B 类的加载
是指将类的class文件加载进内存,并且为之创建一个java.lang.Class对象
C 类的加载时机
创建类的实例 Student stu = new Student();
访问类的静态成员 Calender.getInstance()
初始化类的子类 Public Class student extends Person{} Student stu = new Student();
反射方式创建类的Class对象 clazz.forName("正名")
D.类加载器
三个类加载器:
Bootstrap ClassLoader(根加载器);
Extension ClassLoader(扩展类加载器);
System ClassLoader()系统加载器;
2.3 Constructor
A Constructor : 构造器对象,属于java.base模块,java.lang.reflect包
B 通过Class对象获取构造器对象
Class clazz = Class.forName("path"); 实例化Class对象
clazz.getDeclaredConstructor(Class<?>… parameterTypes) 获取私有构造函数
clazz.getConstructors() 获取所有(不含私有)构造函数的数组
Constructor con = clazz.getConstructor(); 获取一个公共的空参构造函数
C Constructor的常用方法
con.newInstance() 实例化,必须有空参构造
con.newInstance("张三", 15) 实例化,必须存在有参构造
con.getName() 返回构造函数名
2.4 Method
A Method, 方法对象,属于java.base模块,java.lang.reflect包
B 通过Class对象获取Method对象
clazz.getMethod(String name, Class<?>… parameterTypes) 获取一个公共成员方法
clazz.getMethods() 获取所有公共方法(不含私有)
clazz.getDeclaredMethod(String, Class<?>…) 获取一个私有成员方法
C Method的常用方法
method1.getName() 获取此方法名称
method1.invoke(Object obj, Object… args) 指定对象上调用此方法,参数为args
2.5 Field
A Field : 域(属性、成员变量)对象,属于java.base模块,java.lang.reflect包
B 通过Class对象获取属性
clazz.getField(String name) 获取一个公共属性
clazz.getDeclaredField(String name) 获取一个私有属性
clazz.getDeclaredFields() 获取此类所有(含私有)属性
C Field的常用方法
field.getName() 获取该成员属性名称
field.setAccessible(boolean flag) 将此属性的可访问性设置为指定布尔值,是否暴力反射