javap命令

image.png
反编译class文件命令:javap -v -p JVMTest2 > 1.txt
不需要跟后缀名,反编译只会反编译.class文件

反编译信息

  • 第一部分描述信息:记录了class文件存储的位置,什么时候修改过,class文件的md5值以及从哪个java类编译出来的

  • 第二部分描述信息:描述了这个类是用什么样版本的JDK编译的,52是JDK8

  • 第三部分常量池
    image.png

  • 第四部分字段信息
    image.png

  • 第五部分方法的信息
    image.png

在整个文件里面有各种各样的指令,这些指令很难直接去看懂,可以参考文章:指令表

类加载过程详解

image.png
当一个类被创建实例/或者被引用到的时候,如果虚拟机发现之前没有加载过这个类,就会通过类加载器(ClassLoader),把class文件加载到内存

加载

  • 读取类的二进制流
  • 把二进制流转为方法区数据结构,并存放到方法区
  • 在Java堆里面产生一个java.lang.Class对象

链接-验证1

  • 作用:验证class文件是不是符合规范
  • 文件格式的验证
    • 是否以0xCAFEBAB开头(可以使用16进制编辑器打开class文件查看)
    • 版本号是否合理

链接-验证2

  • 元数据验证
    • 是否有父类
    • 是否继承了final类(final类不能被继承,如果继承了就有问题)
    • 非抽象类实现了所有抽象方法

链接-验证3

  • 字节码验证(字节码验证是非常复杂的,一个class文件通过了字节码验证,并不代表这个class没有问题,但如果没有通过验证,那必然是有问题的)
    • 运行检查
    • 栈数据类型和操作码操作参数吻合(比如栈空间只有2字节,但实际却需要大于2字节,此时就认为这个字节码是有问题的)
    • 跳转指令指向合理的位置

链接-验证4

  • 符号引用验证
    • 常量池中描述类是否存在
    • 访问的方法或字段是否存在且有足够的权限
  • 可使用-Xverify:none关闭验证(如果事先可以确定你的代码是安全无误的,可以在启动的时候添加参数关闭验证,从而加快类的加载),例如idea,可以加快idea的启动速度
    image.png

链接-准备

  • 作用:为类的静态变量分配内存,初始化为系统的初始值
    • final static修饰的变量:直接赋值为用户定义的值,比如private final static int value = 123, 直接赋值123
    • private static int value = 123, 该阶段的值依然是0

链接-解析

  • 作用:符号引用转换成直接引用
    符号引用就是指在编译期,java类还不知道所引用的对象它的实际地址,所以只能使用一个符号,说我现在想要引用谁,如果想要真正的引用到这些类(Class)/方法(Methodref)/或者变量(Fietdref),就需要把这些符号,转换成能够找到的对象指针,或者是地址偏移量,转换之后的引用就是直接引用;

  • 简单的说,符号引用就是做个标记,说我要引用谁;而直接引用就是真正去引用这个对象
    image.png

初始化1

  • 执行方法,clinit方法由编译器自动收集类里面的所有静态变量的赋值动作及静态语句块合并而成,也叫类构造器方法
    • 初始化的顺序和源文件中的顺序一致
    • 子类的被调用前,会先调用父类的
    • JVM会保证clinit方法的线程安全性
  • 运行例子
    image.png
  • 更换顺序后
    image.png

初始化2

  • 初始化时,如果实例化一个新的对象,会调用方法对实例变量进行初始化,并执行对应的构造方法内的代码

  • 例子及运行顺序1:
    image.png
    image.png

  • 例子及运行顺序2:
    image.png
    image.png
    image.png
    image.png

    • 先执行方法,打印静态方法和静态代码块,子类的方法调用前会先调用父类的方法,所以会先调用Super类的static方法,在去调用Sub的static方法;然后再去执行Super(父类)的构造块和构造方法,再去执行Sub(子类)的构造块和构造方法

初始化完成后就可以使用这个类了,当不使用这个类的时候,可以把它卸载掉;

上述类加载图只是比较常规的类加载流程,事实上类加载的时候并不一定完全按照这个流程去做,比方说解析不一定在初始化之前,也有可能在初始化之后才去做解析

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

总有那些风吹不散的Coding