#Java类的加载,连接和初始化 当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三个步骤来对该类进行初始化。当JVM连续完成这三步骤后则称类加载/类初始化完成。
- 类的加载:由类加载器完成,加载器由JVM提供。还可以通过继承ClassLoader基类来创建自己的类加载器
- 类的连接:当类被加载后,系统生成一个对应的Class对象,然后进入连接阶段,将会把类的二进制数据合并到JRE中。连接又分为
- 验证:检验被加载的类是否有正确的内部结构,并和其他类协调一致
- 准备:类准备阶段负责为类的类变量分配内存,并设置默认初始值
- 解析:将类的二进制数据中的符号引用替换成直接引用
- 类的初始化:虚拟机对类进行初始化,主要是对类变量进行初始化 有俩种方式
- 声明类变量时指定初始值
- 使用静态初始化块为类变量指定初始值
//声明变量a时指定初始值static int a = 9;static int b ;static { //静态方法块指定变量b的值 b = 3;}复制代码
###类初始化的时机
- 创建类的实例:就是new一个类
- 调用某个类的类方法(静态方法)
- 访问某个类或接口的类变量,或为该类变量赋值
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class 对象。如Class.forName("person")
- 初始化某个类的子类。当某个类的子类被初始化,该子类所有的父类都会被初始化
- 直接使用java.exe命令运行某个之类。当程序运行某个主类,程序会先初始化该主类。
###反射 Java程序运行时都会出现俩种类型:编译时类型和运行时类型,Person p = new Strudent(): 运行代码后生成的p变量,编译时类型为Person,运行时类型为Student 当编译时无法预知对象和类可能属于哪些类,程序只能靠运行时信息来发现对象和类的真实信息,这就必须使用反射 ####获得Class对象
- 使用Class类的
forName(String clazzName)
静态方法 - 调用某个类的class属性来获取该类对应的Class对象。例Person.class来获取Person类对应的对象(最安全,性能最好)
- 调用某个对象的getClass()方法。