美文网首页
深入理解字节码-常量池Constant pool

深入理解字节码-常量池Constant pool

作者: lz做过前端 | 来源:发表于2021-11-13 23:34 被阅读0次

一些概念

  • 对于class字节码,紧接着魔数和大小版本信息后就是常量池了,与其他项目关联最多,同时也是第一个出现的表类型数据项目。
  • 由于常量池是多个表,所以前置了一个数量计数器,而且是从1开始计数的,所以需要-1。
  • 空出索引值0是为了后面的数据需要表示“不引用任何一个常量池项目”,这样就可以把索引值置为0

常量池大分类

  • 自己理解:其实这里的两大分类是一种概念的总结
  • 字面量(Literal)
    • 字面量比较接近于Java语言层面的常量概念:文本字符串、申明为final的常量值(整型、浮点型、长整型、双精度浮点型、字符串类型)
    • todo 请问,申明为final的对象常量是怎样表示的?写个例子查看javap。常量类
  • 符号引用
    • 符号引用则属于编译原理方面的概念
    • 包含:类和接口的全限定名(Fully Qualified Name)、字段的名称和描述符(Descriptor)、方法的名称和描述符
    • 具体:类或接口的符号引用、字段的符号引用、类中方法的符号引用、接口中方法的符号引用、字段或方法的部分符号引用
    • Java代码在进行Javac编译的时候,并不像C和C++那样有“连接”这一步骤(最终内存布局信息),而是进行动态连接。当虚拟机运行时:从常量池获取符号引用(最终是字面量)==>解析并翻译到具体的内存地址中。

常量池项目类型

注:Utf8 ==> CONSTANT_Utf8_info,其他雷同

常量 项目 类型 描述
Utf8
UTF-8编码的字符串
tag u1 值为1
length u2 UTF-8编码的字符串占用了字节数
bytes u1 长度为length的UTF-8编码的字符串
Integer
整型字面量
tag u1 值为3
bytes u4 按照高位在前存储的int值
Float
浮点型字面量
tag u1 值为4
bytes u4 按照高位在前存储的float值
Long
长整型字面量
tag u1 值为5
bytes u8 按照高位在前存储的long值
Double
双精度浮点型字面量
tag u1 值为6
bytes u8 按照高位在前存储的double值
Class
类或接口的符号引用
tag u1 值为7
index u2 指向全限定名常量项的索引
String
字符串类型字面量
tag u1 值为8
index u2 指向字符串字面量的索引
Fieldref
字段的符号引用
tag u1 值为9
index u2 指向声明字段的类或接口描述符Class的索引项
index u2 指向字段描述符NameAndType的索引项
Methodref
类中方法的符号引用
tag u1 值为10
index u2 指向声明方法的类描述符Class的索引项
index u2 指向名称及类型描述符NameAndType的索引项
InterfaceMethodref
接口中方法的符号引用
tag u1 值为11
index u2 指向声明方法的接口描述符Class的索引项
index u2 指向名称及类型描述符NameAndType的索引项
NameAndType
字段或方法的部分符号引用
tag u1 值为12
index u2 指向该字段或方法名称常量项的索引
index u2 指向该字段或方法描述符常量项的索引

补充

  • “I”、“V”、“<init>”、“LineNumberTable”、“LocalVariableTable”等这些没有在代码出现过的常量从哪来?
  • 后面的字段表、方法表、属性表会用到,用于描述一些不方便使用“固定字节”来表达的内容:方法的返回值是什么?有几个参数?每个参数的类型是什么?因为Java的类是无穷无尽的,无法只通过简单的无符号字节描述一个方法用到了哪些类,因此在描述方法的这些信息时,需要引用常量表中的符号引用进行表达。
  • 注意,如果依赖的其他类有常量,也会编译到当前类所在的静态常量池中,在类加载的时候会进入运行时常量池。
  • 总之,编译成字节码的过程,会把用到的所有属性和方法以及代码中涉及到的类、方法、变量的字面量和符号引用编译到常量池中,而引用类型会把类的常量编译进来。这里与类加载无关。

示例

public class StringByteCode {

    private final String finalStr = "finalStr";

    private static String staticStr1;

    private static final String staticFinalStr1;

    private static String staticStr2 = "staticStr2";

    private static final String staticFinalStr2 = "staticFinalStr2";

    private final String finalObjStr = new String("finalObjStr");

    private static String staticObjStr1;

    private static final String staticFinalObjStr1;

    private static String staticObjStr2 = new String("staticObjStr2");

    private static final String staticFinalObjStr2 = new String("staticFinalObjStr2");

    static {
        staticStr1 = "staticStr1";
        staticFinalStr1 = "staticFinalStr1";

        staticObjStr1 = new String("staticObjStr1");
        staticFinalObjStr1 = new String("staticFinalObjStr1");
    }

    public static void main(String[] args) {
        String s1 = "s1";
        String s2 = "s2";
        String s3 = s1 + s2;
        String os1 = new String("s1");
        String os2 = new String("s2");
        String os3 = os1 + os2;
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
        System.out.println(os1);
        System.out.println(os2);
        System.out.println(os3);
    }
}

字节码部分我就不贴出来了,可以使用javap -c -verbose自己打印看看

相关文章

  • 深入理解字节码-常量池Constant pool

    一些概念 对于class字节码,紧接着魔数和大小版本信息后就是常量池了,与其他项目关联最多,同时也是第一个出现的表...

  • 常量池表中的字面量和符号引用

    constant_pool [](常量池) constant_pool 是一种表结构,以1 ~ constant_...

  • 常量池计数器

    constant_pool_count(常量池计数器) 由于常量池的数量不固定,时长时短,所以需要放置两个字节来表...

  • JVM(六)JVM常量池

    1.常量池类型 Java中的常量池分为三种: 类文件常量池(静态常量池)(The Constant Pool)运行...

  • 类常量池和运行时常量池的区别

    首先常量池分为类编译后的常量池和运行时常量池类的常量池为类编译后生成的 Constant pool:在代码运行时会...

  • Java-常量池

    相关概念 常量池的定义常量池(constant pool):指的是在编译期被确定,并被保存在已编译的.class文...

  • 面试系列(2)Java String

    1、常量池 Java 被编译成 class 文件时,会生成一个常量池(Constant pool)的数据结构,用于...

  • JVM-常量池

    1,(全局)字符串常量池(String Constant Pool) 1)使用sun.jvm.hotspot.me...

  • int和Integer的区别(equals和==)

    在这里,我首先讲一下常量池的概念和在jvm里面内存存储情况。 1:常量池(constant pool),指基本数...

  • Java虚拟机-字节码指令

    1 字节码指令 Java字节码指令的执行离不开操作数栈,局部变量表,和常量池。 2 常量池 对于字节码指定来说,常...

网友评论

      本文标题:深入理解字节码-常量池Constant pool

      本文链接:https://www.haomeiwen.com/subject/xmbzzltx.html