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