类加载器
类加载器
什么是类加载器
负责将.class文件(存储的物理文件)加载到内存中
类加载的过程
类加载的时机
- 创建类的实例(对象)
- 调用类的方法
- 访问类或者接口的类变量,或者为该类变量赋值
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
- 初始化某个类的子类
- 直接使用java.exe命令来运行某个主类
用到就加载,不用不加载
类加载的过程
加载
- 通过包名+类名,获取这个类,准备用流进行传输
- 通过一个类的全限定名来获取定义此类的二进制字节流
- 在这个类加载到内存中
- 将这个字节流锁代表的静态存储结构转换为运行时数据结构
- 加载完毕创建一个class对象
- 在内存中生成一个代表这个类的java.land.Class对象,任何类被使用时,系统都会为之建立一个java.lang.Class对象
验证
- 文件中的信息是否符合虚拟机规范,有没有安全隐患
准备
- 负责为类的类变量(被static修饰的变量)分配内存,并设置默认初始化值。
解析
- 将类的二进制数据流中的符号引用替换为直接引用
- 如果本类中用到了其他类,此时就需要找到对应的类
初始化
- 根据程序员通过程序制定的主观计划去初始化类变量和其他资源
- 静态变量赋值以及初始化其他资源
类加载器的分类
- 启动类加载器(Bootstrap ClassLoader):虚拟机内置的加载器
- 平台类加载器(Platform ClassLoader): 负责加载JDK中一些特殊的模块
- 系统类加载器(System ClassLoader): 负责加载用户类路径上所指定的类库
双亲委派模型
加载器之间的层次关系。层次由低到高:自定义类加载器>>系统类加载器>>平台类加载器>>启动类加载器
ClassLoader中有静态方法:getSystemClassLoader()
方法,可以获取系统类加载器。然后getParent()
会得到更高一层次的加载器。
加载过程:会首先有低层次逐层次调用加载器,最终会调用启动类加载器,当启动类加载器无法完成类的加载时,会有层次由高至低,逐层返回,最终完成类的加载。
类加载器的方法
// 获取一个系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
// 通过系统类加载器加载资源文件,参数为资源文件文件路径
InputStream is = systemClassLoader.getResourceAsStream("prop.properties");
Properties prop = new Properties();
prop.load(is);
System.out.println(prop);
is.close();
//prop.properties文件要放在Src目录下
// 4 通过反射创建对象并调用方法
// 4.1 获取Class对象
Class clazz = Class.forName(props.getProperty("className"));
// 获取构造器对象
Constructor constructor = clazz.getConstructor();
// 创建对象
Object o = constructor.newInstance();
// 获取方法对象
Method method = clazz.getMethod(props.getProperty("methodName"));
// 运行方法
method.invoke(o);
// 释放资源
is.close();