7. 类加载机制 7.1 类的加载、连接、初始化

 

类加载机制概述:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是java虚拟机的机制

 

 

1. Java程序执行时遵循以下顺序

  1.1. 加载:将类的.class文件中的二进制数据装载到内存中,将其放在运行时数据区方法区内,然后在堆区创建一个java.lang.Object对象,用来封装类在方法区的数据结构

    1.1.1. 加载.class方式:

      1.1.1.1. 从本地系统中加载

      1.1.1.2. 通过网络下载.class

      1.1.1.3. 从zip、jar等文件中加载.class

      1.1.1.4. 从数据库中提取.class

      1.1.1.5. 将Java源文件动态编译成.class

  1.2. 连接:

    1.2.1. 验证:确保被加载的类的正确性(防止恶意用户手工构造.class文件)

      1.2.1.1. 类文件的结构检查:确保类文件遵从Java类文件的固定格式

      1.2.1.2. 语义检查:确保类本身符合Java语言的语法规则(例如:final类型的类没有子类)

      1.2.1.3. 字节码验证:确保字节码流(包括静态方法和实例方法)能被Java虚拟机安全执行

      1.2.1.4. 二进制兼容性验证:确保相互应用的类之间协调一致(例如:NosuchMethodError)

    1.2.2. 准备:为类的静态变量分配内存,并将其初始化为默认值

    1.2.3. 解析:把类中的符号引用转换为直接引用:

public class Car{
   public void run(){}   
}

public class Worker{
   public void work(){
       Car car = new Car();
       car.run();   //这段代码在Worker类的二进制数据中表示为符号引用
   }   
}
在Worker类的二进制数据中,包含了一个对Car类的run()方法的符号引用,它由run()方法的全名和相关描述组成。
解析阶段,Java虚拟机会把这个符号引用替换为一个指针,该指针指向Car类的run()方法在方法区内的内存位置,这个指针就是直接引用

  1.3. 初始化:为类的静态变量赋予正确的初始值

    1.3.1. 静态变量初始化方式:

      1.3.1.1. 在静态变量声明处初始化

      1.3.1.2. 在静态代码块中初始化

Notice : 准备的初始化为默认值与初始化赋予正确的初始值不是一个意思

public class Student {
    private static int a = 1;
}

准备阶段,a的默认值是0,初始化的阶段a才等于3

上面这个过程等同于以下代码:

public class Student {
    private static int a;
    static{
        a = 3;  
    }   
}

2. 只有静态变量在准备阶段才被初始化,那么类在什么时候初始化呢?

public class Handsome{
  public static int a =1;     
  public static void sayHi(){}   
}

public class Child extends Handsome{
  private static int b = 2;   
public static void main(String [] args){
    Child.b = 3;
  } }

Java程序对类的使用方式分为两种:

  1.1. 主动使用(6种)

    1.1.1:创建类的实例 --> new Handsome()

    1.1.2:访问某个类或接口的静态变量,或者对该静态变量赋值 --> Handsome.a = 2

    1.1.3:调用类的静态方法 --> Handsome.sayHi()

    1.1.4:反射 --> Class.forName("Handsome")

    1.1.5:初始化一个类的子类 --> Child.b = 3

    1.1.6:Java虚拟机启动时被标明为启动类的类 --> 含main方法启动的类

  1.2. 被动使用: 除开上面6种的其他方式,都不会导致类被初始化

3. 每个类或接口被Java程序“首次主动使用”时才初始化

 

下一篇:7.2类加载器

posted @ 2018-07-20 15:22  君哥~  阅读(244)  评论(0编辑  收藏  举报