# 类加载器
# 类加载
# 类加载
- JVM 通过类的加载,类的连接,类的初始化对类进行初始化
- 类的加载:class 文件读入内存,创建
java.lang.Class
对象
# 类的连接
- 验证:检验类
- 准备:分配内存,设置默认初始化值
# 类的初始化
- 对类变量进行初始化
- 类没被加载或连接 -> 先加载并连接
- 父类为初始化 -> 初始化直接父类 (最先初始化 Object 类)
- 类中有初始化语句 -> 执行初始化语句
# 类的初始化时机
- 创建对象,调用方法
- 初始化子类
- java.exe 命令运行主类
- 反射创建类或接口的
java.lang.Class
对象
# 类加载器的作用
将.class 加载到内存,生成 java.lang.Class 对象
# JVM 的类加载机制
- 全盘负责:加载类及其相关类
- 父类委托:让父类加载器加载
- 缓存机制:用过的类有缓存
# 加载器的分类
Bootstrap class loader
:内置类加载器,通常表示为 nullPlatform class loader
:平台类加载器,加载 api,运行时类System class loader
:应用程序类加载器,定义应用程序,模块路径
# ClassLoader 类方法
static classLoader getSystemClassLoader()
:返回用于委派的系统类加载器ClassLoader getParent()
:返回父类加载器进行委派
# 反射
# 反射概述
- 通过类加载器加载的.class 文件对象的 Class 类进行调用
- 反射是框架设计的灵魂
- 框架:半成品软件。可以在框架基础上进行软件开发,简化编码
# 反射机制
将类的各个组成部分封装成其他对象
# 反射优点
- 可以在程序运行中操作对象 idea
- 可以解耦,提高程序可扩展性
# Java 代码的三个阶段
- Source 源代码:*.java ->(javac 编译) *.class
- Class 类对象:*.class ->(ClassLoader 类加载器) class 类对象
- Runtime 运行阶段:创建对象
# 获取 class 对象的方式
# Class.forName()
Source 源代码阶段: Class.forName("com.bjh.Student")
- Class 类的静态方法
- 将字节码文件加载进内存,返回 class 对象
# 类名.class
Class 类对象阶段: 类名.class
通过类名的属性返回 class 对象
# 对象.getClass ()
Runtime 运行阶段: 对象.getClass()
- 定义再 Object 类中
- 同一个字节码文件 (*.class) 在一次程序运行中只会加载一次
# Class 对象功能
# 获取成员的方法
Field[] getFields(); // 获取所有 public 修饰的成员 | |
File getField(String name); // 获取指定名称的 public 修饰成员 | |
Field[] getDeclaredFields(); // 获取所有成员 | |
File getDeclaredField(String name); // 获取指定名称的成员 |
Field 成员变量:
- 设置值:
void set(Object obj, Object value)
- 获取值:
get(Object obj)
暴力反射(忽略权限修饰符的安全检查): 变量对象.setAccessible(true);
# 获取构造方法
Constructor<?>[] getConstructor() | |
Constructor<T> getConstructor(类<?>... parameterTypes) // 指定构造方法的参数 String.class int.class ... | |
Constructor<?>[] getDeclaredConstructor() | |
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes) |
Constructor 构造方法: Object obj = 构造方法对象.newInstance(构造)
# 获取成员方法
Method[] getMethods() | |
Method getMethods(String name, 类<?>... parameterTypes | |
Method[] getDeclaredMethods() | |
Method getDeclaredMethods(String name, 类<?>... parameterTypes) |
Method 方法对象:
- 执行方法:
方法对象.invoke(Object obj, Object...args);
- 获取方法名:
String getName()
# 获取类名
String getName(); |
# 越过泛型检查
List<Integer> list = new ArrayList<>(); | |
list.add(123); | |
Method m = list.getClass().getMethod("add", Object.class); | |
m.invoke(list,"hello"); | |
System.out.println(list); |
# 运行配置文件的指定方法
className=... | |
methodName=... |
Properties prop = new Properties(); | |
prop.load(new FileReader("xxx.txt")); | |
Class<?> c = Class.forName(prop.getProperty("className")); | |
Method m =c.getMethod(prop.getProperty("methodName")); | |
Object obj = c.newInstance(); | |
m.invoke(obj); |
# 模块化使用
Java9 退出模块化
- 在模块的 scr 目录下新建
module-info.java
的描述文件 - 对于导出模块:
exports 包名;
- 对于导入模块:
requires 包名;
# 模块化服务的使用
# 导出模块
描述文件: provides 接口名 with 实现类
# 导入模块
- 描述文件:
uses 接口名
- 加载服务:
ServiceLoader<接口名> 变量名 = ServiceLoader.Load(导出模块名.class);
- 遍历服务:
for(接口名 变量名 : 变量名){ | |
变量名.接口内的方法(); // 实现其模块化实现类的方法 | |
} |