Java反射
JAVA反射
类加载器
类加载/类初始化
三个步骤
类的加载: 将class文件读入内存,并为之创建一个java.lang.Class对象
任何类被使用时,系统都会为之建立一个java.lang.Class对象
系统中所有的类都是java.lang.Class的实例。
类的连接
- 验证阶段:检验被加载类是否有正确的内部结构,并和其他类协调一致
- 准备阶段:负责为类的类变量分配内存,并设置默认初始化值
- 解析阶段:将类的二进制数据中的符号引用替换为直接引用
类的初始化:主要是对类变量初始化
- 假如该类还没被加载和连接,则先加载并连接该类
- 假如该类的直接父类还没被初始化,先初始化其直接父类(会向上递归,java中最先初始化的是Object类)
- 假如类中有初始化语句,则系统依次执行这些初始化语句
类的初始化时机:
- 创建类的实例
- 调用类的类方法
- 访问类或接口的类变量,或为该类变量赋值
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
- 初始化某个类的子类
- 直接使用java.exe命令来运行某个主类
类加载器
作用
- 将.class文件加载到内存中,并为之生成对应的java.lang.Class对象
java虚拟机的类加载机制
内置类加载器
Bootstrap class loader–>Platform class loader–>System class loader
父到子的顺序
反射
概述
指在运行时获取一个类的变量和方法信息,然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,程序不用在编译器就完成确定,在运行起仍可以拓展
获取Class对象
- 使用类的class属性,e.g.
Student.class
- 调用类的getClass()方法(这是Object类的方法,所有对象都有该方法)
- Class类中的静态方法,forName(String className),该方法要传入字符串参数,该字符串是某个类的全路径,也就是完整包名的路径
1 | Class<Student> c1=Student.class; |
反射构造方法
1 | //反射构造方法并使用 |
基本数据类型也可以通过.class方法得到class对象,getConstructor方法需要传入的参数都是class类型,并且是当前想要访问的构造方法的形参
1 | //反射练习 |
- getDeclaredConstructor可获取所有访问权限的构造方法
- getConstructor只能得到public权限的构造方法
遍历数组简便写法
1
2
3 for(Field filed: fields){
System.out.println(filed);
}
通过反射得到成员变量
1 | //反射获取成员变量 |
1 | //练习 |
反射获取成员方法
注:
getDeclaredMethods
方法只有本类的所有方法,没有由类或接口声明的对象以及从超类或超级接口继承的类
1 | //反射获取成员方法 |
1 | //练习 |
练习
在ArrayList
中插入一个字符串数据–越过泛型检查 1
2
3
4
5
6
7
8
9
10
11
12ArrayList<Integer> array=new ArrayList<Integer>();
array.add(10);
array.add(20);
//array.add("asa");//报错
System.out.println(array);//[10, 20]
Class<? extends ArrayList> c = array.getClass();
//获取到原始方法,从而绕过泛型检查
Method m = c.getMethod("add", Object.class);
m.invoke(array,"hello");
m.invoke(array,"sqhy");
m.invoke(array,"zql");
System.out.println(array);运行配置文件运行类的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22/* 配置文件
class.txt
className=xxx
methodName=xxx
*/
/* className=com.itheima.S
methodName=study
*/
//加载数据
Properties prop=new Properties();
FileReader fr=new FileReader("./class.txt");//相对路径,这里.表示总文件夹(src的上一级)
prop.load(fr);
fr.close();
//通过键名获取值
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");
//通过反射使用
Class<?> c = Class.forName(className);//com.itheima.S
Constructor<?> con = c.getConstructor();
Object obj = con.newInstance();
Method m = c.getMethod(methodName);//study
m.invoke(obj);
- 标题: Java反射
- 作者: Sl0th
- 创建于 : 2022-08-23 22:50:09
- 更新于 : 2024-11-11 18:23:06
- 链接: http://sl0th.top/2022/08/23/Java反射/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论