一、类的加载
当程序要使用某个类时,如果该类还没有被加载到内存中,则系统会通过加载、连接、初始化三步来实现对这个类进行初始化。
加载:就是指将class文件读入到内存中,并为之创建一个Class对象。任何类被使用的时候,系统都会建立一个Class对象。
连接:1)验证 是否有正确的内部结构,并和其他类协调一致 2)准备 负责为类的静态成员分配内存,并设置默认初始化值 3)解析 将类的二进制数据中的符号引用替换为直接引用。
初始化:就是进行属性初始化、构造初始化等等。
二、类的初始化时机
1.创建类的实例
2.访问类的静态变量,或者为静态变量赋值
3.访问类的静态方法
4.使用反射方式来强化自创建某个类或者接口对应的Class对象
5.初始化某个类的子类
6.直接使用java.exe命令来运行某个朱磊
三、类加载器
负责将.class文件加载到内存中,并为之生成对应的Class对象。
虽然我们不需要关系类的加载机制,但是了解这个机制,我们就能更好的理解程序的运行。
类加载器的组成:
根类加载器:BootStrap ClassLoader,也称为引导类加载器,负责java核心类的加载,比如System、String等。在JDK中JRE的lib目录下rt.jar文件中。
扩展类加载器:Extension ClassLoader,负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录中的ext目录。
系统类加载器:System ClassLoader,负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和路径。
通过上面的描述,我们知道我们常用的东西的加载都是由谁来完成的,到目前为止,我们已经知道把class文件加载到内存了,那么,如果我们仅仅站在这些class文件的角度,我们如果来使用这些class文件的内容呢?这就是反射
四、反射
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能被称为java语言的反射机制。
要想解剖一个类,必须先获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对应的Class类型的对象。
反射获取class文件对象的三种方式
package cn7; /** * 反射:就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。 * * 要想这样使用,首先你必须得到class文件镀锡,其实也就是得到Class类的对象。 * Class类: * 成员变量 Field * 构造方法 Constructor * 成员方法 Method * 获取class文件对象的方式: * 1.Object类的getClass()方法 * 2.数据类型的静态属性class * 3.Class类中的静态方法forName(String className) * * 一般我们在开发中使用的是第三种,因为它传入的是一个字符串,而不是一个具体的类名,这样我们就可以把这样的字符串配置到配置文件中。 */ publicclass ReflectDemo { publicstaticvoid main(String[] args) throws Exception { //方式1 Person p = new Person(); Class<? extends Person> c = p.getClass(); Person p2 = new Person(); Class<? extends Person> c2 = p2.getClass(); System.out.println(p == p2);//false System.out.println(c==c2);//true //方式2 Class<? extends Person> c3 = Person.class; System.out.println(c2==c3);//true //方式3 Class<?> c4 = Class.forName("cn7.Person"); System.out.println(c == c4);//true } }