• JVM-class文件完全解析-常量池


      在.java文件,讲过javac编译后产生的 .class文件中,头4个字节表示的是魔数,接着魔数后面的第5,6个字节存储的是次版本号,第7,8个字节存储的主板本号.那么再接下来的就是表示常量池入口了. 

    常量池 

      可以理解为class文件之中的资源仓库,它是class文件结构中与其他项目关联最多的数据类型,也是占用class文件空间最大的数据项目之一,同时它还是class文件中第一个出现表类型的数据项目.

       由于常量池的数量是不固定的,所以在常量池入口需要放置一项u2(即2个字节)类型的数据,代表常量池容量计数值(constant-pool-count)(从1开始,将0表示不引用任何常量).

      常量池中主要存放两大类常量:字面量(Literal)和符号引用(Synbolic Reference).

    • 字面量:比较接近于Java语言层面的常量概念,如文本字符串,声明为final的常量值.
    • 符号引用:包括如下三类常量:
    1. 类和接口的全限定名(Fully Qualified Name)
    2. 字段的名称和描述符(Descriptor)
    3. 方法的名称和描述符 

    常量池中每一项常量都是一个表(14种表). 

    类型 标志 描述 
    CONSTANT_utf8_info 1  UTF-8编码的字符串
    CONSTANT_Integer_info 3 整形字面量
    CONSTANT_Float_info 4 浮点型字面量
    CONSTANT_Long_info 长整型字面量
    CONSTANT_Double_info 双精度浮点型字面量
    CONSTANT_Class_info 类或接口的符号引用
    CONSTANT_String_info 字符串类型字面量
    CONSTANT_Fieldref_info 字段的符号引用
    CONSTANT_Methodref_info 10 类中方法的符号引用
    CONSTANT_InterfaceMethodref_info 11 接口中方法的符号引用
    CONSTANT_NameAndType_info 12 字段或方法的符号引用
    CONSTANT_MothodType_info 16 标志方法类型
    CONSTANT_MethodHandle_info 15 表示方法句柄
    CONSTANT_InvokeDynamic_info 18 表示一个动态方法调用点

      注意:在这14种表有一个共同的特点,就是开始的第一位是一个u1类型的标志位(tag,就是上表中的标志这一列),代表当前这个常量属于哪种常量类型.下面分析实例的时候会用到.

       由于class文件中方法,字段等都需要引用CONSTANT_utf8_info类型常量来描述名称,所以CONSTANT_utf8_info类型常量的最大长度也就是Java中方法,字段名的最大长度(Java程序中如果定义了超过64KB英文字符的变量或方法名,将无法编译).

    下面我们接着上一篇分析的class文件继续往下走.

      这张图中,我们继续分析了接着主版本号接下来的几个字节,首先是常量池入口是0x0013,转化为十进制就是19,那么表示的范围就是1~18,因为0用来表示不引用任何常量池了.那么也就是说0x0013之后有18个常量池.我们看紧接着的一个常量池,十六进制0x0a用十进制表示就是10,通过上表的标志列我们可以直到,10对应的那一行就是CONSTANT_Methodref_info类型的表,是类中方法的符号引用.那么知道了是CONSTANT_Methodref_info表,就可以根据CONSTANT_Methodref_info表的结构继续往下分析,一直到分析完18个常量池.在这里就不一一往下分析了,直接通过javap工具来直接查看,也顺便查看我们分析的对不对.

     

     

    我们从javap的结果看出,常量池的范围就是1~18,然后第一个常量池就是Method,也即CONSTANT_Methodref_info.
  • 相关阅读:
    就打排序算法总结
    php 垃圾回收机制写时复制和引用计数
    zend studio 使用断点调试
    SiteServer 迁移至 Windows 2008 R2 问题汇总
    [项目改造中的点滴]C#中IDataReader和DataSet的区别与使用场景
    顺序分支知识总结
    我的第一篇博客
    [原创]删除GRUB引导恢复Windows引导,不用下载任何工具
    在C++builder中使用正则表达式,非boost库,简单!~
    SQL 存储过程优化经验
  • 原文地址:https://www.cnblogs.com/lrh-xl/p/5334755.html
Copyright © 2020-2023  润新知