类加载器 负责将.class文件加载到内存中,让JVM执行
- 类加载的过程
- 加载时机 用到就加载,不用不加载
- 创建类的对象
- 调用类的静态方法
- 访问类或者接口的静态变量,或者为该变量赋值
- 使用反射来强制创建某个类或接口对应的java.lang.Class对象
- 初始化类的子类
- 直接使用java.exe命令来运行某个主类
- 加载具体过程
- 加载
- 通过类的全限定类名来获取定义此类的二进制字节流
- 将这个字节流所代表的静态存储结构转换为运行时数据结构,把字节码文件加载到内存中
- 在内存中生成一个代表这个类的java.lang.Class对象
- 链接
- 验证 这一阶段为了确保Class文件字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身安全
- 准备 为类的静态变量分配内存,并设置默认初始值
- 解析 将类的二进制数据流中的符号引用替换为直接引用,其他类的引用开始是用符号代替,找到该类后才会直接替换为该类
- 初始化 静态变量赋值以及初始化其他资源
- 加载
- 加载时机 用到就加载,不用不加载
- 类加载器的分类
- 启动类加载器 虚拟机内置的类加载器
- 平台类加载器 负责加载JDK中一些特殊的模块
- 系统类加载器 负责加载用户类路径上所指定的类库
- 双亲委派模型
- 调用类加载器的时候,会委派给逻辑上的父类加载器,直到最顶层。如果最顶层加载不了就会返回给子加载器,知道最底层
反射 利用反射调用类中的属性和方法时,无视修饰符
- 获取Class对象,一个类的Class对象是唯一的
- 源代码阶段
- 字节码文件还没有被加载到内存中
- 使用Class类中的静态方法 forName(String name) 获得Class对象
- 这个方法会把字节码文件加载到内存中
- Class对象阶段
- 被加载到内存中并创建了对象
- 通过类名.class获得Class对象
- Runtime运行时阶段
- new Student() 自己真正创建对象的时候
- 通过对象.getClass()
- 源代码阶段
- Class对象记录了一个类的所有信息
- 所有的成员变量,都用Field描述
- 所有的构造方法,都用Constructor描述
- 所有的成员方法,都用Method描述
- 用获取到的Class对象获取Constructor对象
- Constructor<?>[] getConstructors() 返回所有公共构造方法对象的数组
- Constructor<?>[] getDeclaredConstructors() 返回所有构造方法对象的数组(包括私有)
- Constructor<T> getConstructor(class<?>… paramterTypes) 返回指定的公共构造方法对象
- Constructor<T> getDeclaredConstructor(class<?>… paramterTypes) 返回指定的构造方法对象(包括私有)
- 获取指定构造方法对象时,参数传递和构造方法一致即可
- 用获取到的Construcor对象创建对象
- newInstance(Object… initargs)
- 私有构造方法不能直接调用这个方法创建对象,必须使用需要先临时取消访问检查,setAccessible(true)
- 用获取到的Class对象获取Field对象
- Field[] getFields() 返回所有公共成员变量对象的数组
- Field[] getDeclaredFields() 返回所有成员变量对象的数组(包括私有)
- Field getField(String name) 返回指定公共成员变量对象的数组
- Field getDeclaredField(String name) 返回指定成员变量对象的数组(包括私有)
- 用获取到的Field对象赋值或者取值
- void set(Object obj, Object value) 给指定对象的成员变量赋值
- Object get(Object obj) 返回指定对象的变量值
- 用获取到的Class对象获取Method对象
- Method[] getMethods() 返回所有公共成员方法对象的数组,包括继承的
- Method[] getDeclaredMethods() 返回所有成员方法对象的数组,不包括继承的
- Method getMethod(String name, Class<?>… parameterTypes) 返回指定公共成员方法对象
- Method getDeclaredMethod(String name, Class<?>… parameterTypes) 返回指定成员方法对象(包括私有)
- 用获取到的Method对象运行方法
- Objectinvoke(Object obj, Object… args) 用指定对象调用该方法