一、类加载器
类加载器负责将.class文件(存储的物理文件)加载到内存中
类加载的时机:
1. 创建类的实例
2. 调用类的类方法
3. 访问类或接口的类变量,或者为该类变量赋值
4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
5. 初始化某个类的子类
6. 直接使用java.exe命令来运行某个主类
类加载的过程:
其中验证、准备、解析这三步属于连接的过程
加载
1. 通过类的全限定名来获取定义此类的二进制字节流
2. 将这个字节流所代表的静态存储结构转化为运行时数据结构(加载到内存中)
3. 在内存中生成一个代表这个类的java.lang.Class对象(任何类被使用时,系统都会为它建立一个java.lang.Class对象)
连接
1. 验证:确保Class文件字节流中包含的信息符合虚拟机要求,不会危害虚拟机自身安全
2. 准备:为类的类变量分配内存,并设置默认初始化值
3. 解析:将二进制数据流中的符号引用替换为直接引用,意思是找到需要用到的类
初始化:
根据程序员通过程序制定的主观计划去初始化类变量和其他资源(静态变量赋值和初始化其他资源)
类加载器的分类:
启动类加载器(Bootstrap ClassLoader):虚拟机内置的类加载器
平台类加载器(Platform ClassLoader):负责加载JDK中一些特殊的模块
系统类加载器(System ClassLoader):负责加载用户类路径上所指定的类库
双亲委派模型:
● 类加载器收到加载任务时会将加载任务逐层向上传递给父类加载器,最终到达顶层的启动类加载器
● 当启动类加载器不能完成加载任务时,再委托给下层的子类加载器,最终完成类的加载
● ClassLoader对象的getParent()方法可以获取父类加载器
常用方法:
方法名 | 说明 |
public static ClassLoader getSystemClassLoader() | 获取系统类加载器 |
public InputStream getResourceAsStream(String name) | 加载某一个资源文件 |
二、反射
概述:
1. 在运行状态中,对于任何一个类都能知道这个类的所有属性和方法
2. 对于任何一个对象,都能够调用它的任意方法和属性
3. 这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制
获取Class对象:
1. 通过 Class.forName(全类名) 获取,该方法是Class类的静态方法
2. 通过 类名.class 获取
3. 通过 对象.getClass() 获取
4. 注意:这三种方式获取的Class对象是同一个Class对象,一个类在JVM中只会有一个Class对象
反射获取构造方法:
方法名 | 说明 |
Constructor<?>[] getConstructors() | 返回所有公共构造方法对象的数组 |
Constructor<?>[] getDeclaredConstructors() | 返回所有构造方法对象的数组(包括私有) |
Constructor<?> getConstructor(Class<?>...parameterTypes) | 获取单个、公共的构造方法对象,如果是无参构造则该方法参数留空,如果是有参则该方法参数是参数类型的Class对象 |
Constructor<?> getDeclaredConstructor(Class<?>...parameterTypes) | 获取单个、公共或私有的构造方法对象,如果是无参构造则该方法参数留空,如果是有参则该方法参数是参数类型的Class对象 |
由获取的构造方法对象创建对象
1. 可以利用构造方法类Constructor中的 T newInstance(Object...initargs) 方法来创建对象
2. 如果该构造方法是私有的构造方法,则创建对象之前需要使用Constructor类中的 void setAccessible(boolean b) 方法临时取消访问检查
反射获取成员变量:
方法名 | 说明 |
Field[] getFields() | 返回所有公共成员变量对象的数组 |
Field[] getDeclaredFields() | 返回所有成员变量对象的数组 |
Field getField(String name) | 根据变量名获取一个公共成员变量对象 |
Field getDeclaredField(String name) | 根据变量名获取一个成员变量对象 |
由Field对象操作成员变量
1. void set(Object o,Object v) ,设置某个成员变量的值,第一个参数是需要设置成员变
量的对象,第二个参数是成员变量的值
2. Object get(Object o) ,获取某个对象的当前成员变量的值
3. 注意,如果成员变量是私有的,在使用get和set方法时也需要使用setAccessible()方法暂时取消访问检查
反射获取成员方法:
方法名 | 说明 |
Method[] getMethods() | 获取所有公共成员方法对象数组 |
Method[] getDeclaredMethods() | 获取所有成员方法对象数组 |
Method getMethod(String name,Class<?>...parameterTypes) | 获取一个公共的成员方法对象,第一个参数是方法名,第二个参数是方法的参数的Class对象 |
Method getMethod(String name,Class<?>...parameterTypes) | 获取一个公共的成员方法对象,第一个参数是方法名,第二个参数是方法的参数的Class对象 |
由Method对象操作成员方法:
● 使用 Object invoke(Object o,Object...args) 方法可以运行成员方法
● 第一个参数是指调用该方法的对象
● 第二个参数是指该方法的参数
● 返回值Object是成员方法的返回值,如果没有则可以不用接收