一、类加载器
类加载器:用于将字节码文件加载到内存中
二、类加载过程
当我们的程序中要使用类的时候,如果类还没有被加载到内存中,那么类加载器会对该类进行加载、链接、初始化这三步加载进内存中
1、加载
通过类的包名+类名获取该类的二进制字节流,准备用流进行传输
将该类加载到运行时数据区
在内存中创建一个Class对象,该对象作为这个类的各种数据的访问入口
2、链接
将类的二进制数据合并到JRE中
验证:确保加载信息符合JVM规范,保证虚拟机安全
准备:为类的静态变量在方法区分配内存,并设置类变量默认初始值
解析:将虚拟机常量池内的符号引用替换为直接引用
3、初始化
初始化就需要由虚拟机控制,到了初始化阶段才真正执行java代码,类初始化的主要工作是为静态变量赋程序设定的初始值,也就是执行类构造器方法的过程
三、类的主动引用
实例化对象
调用静态变量,或者是给静态变量进行赋值
调用静态方法
运行器运行
通过反射机制强制性的对类或接口的实现类进行实例化
实例化子类对象
四、类加载器的分类
类加载器分类主要分为两类:
JVM内置的类加载器:分别加载不同目录下的class文件
Bootstrap ClassLoader启动类/引导类/根类加载器:负责加载Java核心类,比如:String、Math、System等等。被加载的类都保存在中
Extension ClassLoader扩展类加载器:负责jre的扩展目录中jar包的加载,被加载的类都保存在目录下
App ClassLoader应用类/系统类加载器:负责在jvm启动的时候加载来自java命令的class文件,以及classpath变量所指定的jar包和类路径,第三方jar包也会被加载
用户自定义的类加载器:负责的加载目录自己决定
五、双亲委派模式
双亲委派模式:如果一个类加载器收到了类加载请求,它不会先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,请求最终到达最顶层的启动类加载器,如果父类加载器可以完成加载任务,就成功返回,否则子加载器才会尝试自己加载
六、反射
1、反射概述
反射:在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法,这种动态获取程序信息以及动态调用对象的功能称之为Java语言的反射机制。被private封装的资源只能类内部访问,外部不行,但反射能直接操作类私有属性,反射可以在运行时获取一个类的所有信息(成员变量、成员方法、构造方法等),并且可以操纵类的属性、方法、构造器等
想要通过反射机制获取操纵一个类的所有资源,需要利用类加载器加载class字节码文件时创建的对应的Class对象。
2、获取Class对象
获取Class对象三种方式:
类名.class
对象名.getClass()
Class.forName(包名+类名)
2.1、Class.forName()
代码示例
2.2、类名.class
代码示例
2.3、对象.getClass()
代码示例
3、获取构造器
3.1、获取所有公共构造器
User.java
代码示例
代码示例
3.2、获取无参构造器
代码示例
3.3、获取有参构造器
代码示例
4、暴力反射
反射里的Constructor、Field、Method三个类都有一个getDeclaredXxx方法,可以不受限制的获取私有构造器、属性、方法调用。通过该方法获取私有成员,会自动的访问类的isAccessable,默认是false,如果想获取,那么调用setAccessable设置为true,就可以对类中的私有成员操作了。
代码示例
5、实例化对象
在不手动调用构造器的前提下,利用反射机制直接实例化对象
代码示例
6、成员变量
6.1、获取所有公共属性
代码示例
6.2、获取所有属性
代码示例
6.3、获取指定属性
代码示例
7、成员方法
7.1、获取所有公共成员方法
7.2、获取所有成员方法
7.3、获取无参成员方法
7.4、获取有参成员方法
8、泛型擦除
代码示例
9、配置文件
把一个类的类名和方法名添加到properties文件中,通过反射机制读取内容并调用方法
user.properties
代码示例
领取专属 10元无门槛券
私享最新 技术干货