Java基础03-类的加载过程03(解析、再说初始化)

注:基于《Java高并发编程详解-汪文君》、《深入理解JVM高级特性与最佳实践-周志明》,以学习为目的,加上自身理解、验证。作为笔记,为加深印象,做到不复制,不粘贴。欢迎,大家一起交流学习。

上回最后部分说到类加载阶段过程中关于类接口、字段的解析流程。那么今天就接着上回的内容,从类方法、接口方法的解析开始继续往下学习。

类方法的解析

类方法和接口方法不同,类方法可以直接使用该类进行调用,但是接口方法必须要有相应的实现类继承才能够进行调用。

1.如果在类的方法表中,发现class_index中索引的Resolve是一个接口的话,而不是一个类,直接会返回错误。

2.在Resolve类中,查找是否有方法描述和目标方法完全一致的方法,如果没有,则继续向其父类中去找,否则直接返回这个方法的引用

3.如果在父类中一直没有找到,就意味着查找失败了,会抛出NoSuchMethodErrorException。如果在当前类或者父类中找到了和目标方法一致的方法,但是它是一个抽象的类,会抛出AbstractMethodErrorEcveption。

当然,在类方法查找的过程中,也存在着大量的校验和验证。

接口方法的验证

接口可以定义方法,也可以去继承其他接口。

1.在接口方法表中发现class_index中索引的Resolve是一个类而不是接口,会直接报错。理论上来说,方法接口表中和类接口表中所容纳的类型应该是不一样的。从常量池中有Contant_Methodref_info和Contant_IntefaceMethodredInfo两个不同的类型也可以看出来。

2.接口方法的查找和类方法类似,子类到父类,自上而下。

类的初始化阶段-类加载过程中最后一个阶段

在这个阶段中,最重要的一件事,执行<clinit>()(class_initialize)方法,所有的类变量都会赋予正确的值,也就是程序所制定的值。

<clinit>()方法包含在生成的class文件中,在编译阶段生成。它包含了所有类变量的赋值动作和静态块的执行代码。编译器收集的顺序是由执行语句在源文件中的出现顺序决定的。注意:该方法能够保证顺序性。另外,静态块只能对后面的静态变量进行赋值,单数不能够访问。

注:

1.如果在一个类或者中没有静态代码块,也没有静态变量,那么它就没有<clinit>()方法。

2.<clinit>()方法只能够被虚拟机所执行,类主动使用后会去调用这个方法。

3.JVM保证了该方法在多线程的执行环境下的同步语义,所以在Java的单例模式一文中,看到的Holder实现单例模式是一种比较适合的方式。

类加载过程总结

随着java的不断发展,jvm不断升级,类加载可能会变。但无论怎么变,还是会以class二进制文件加载,连接,类的初始化进行下去。最后,再看下在类加载过程中的这段代码,作为这一个阶段学习的结束。

 1 public class Simple {
 2 
 3     // 1.
 4     private static int x = 0;
 5     private static int y;
 6 
 7     private static Simple instance = new Simple(); // 2.
 8 
 9     private Simple() {
10         x++;
11         y++;
12     }
13     
14     public static Simple getInstance() {
15         return instance;
16     }
17 
18     public static void main(String[] args) {
19         Simple instance = Simple.getInstance();
20         System.out.println(instance.x);
21         System.out.println(instance.y);
22     }
23 
24 }

说明:

  1. 加载二进制文件后,进入到连接阶段,类变量x, y,instance赋予对应的初始值,即 x = 0, y = 0, instance=null,进入到解析阶段。
  2. 解析阶段过后,到初始化阶段,为每一个类变量赋值程序文件中对应的指定值。也就是执行<clinit>方法的过程。执行过后x = 0, y = 0, instance=new Simple()。
  3. 接下来,非常熟悉,在new()的过程中,执行Simple类的构造方法,结果为 x = 1; y = 1。至此,类的加载完成。
原文地址:https://www.cnblogs.com/sunl123/p/11110685.html