.class解读2---常量池(1)

96 阅读2分钟

1.概述

常量池是占据.class文件中很大的一部分

点class文件解读.jpg 从上面的这张图中可以看出,在第1行的K开始截止到第14行的N都是常量池的部分。
在最大版本号后,两个字节表示常量池计数器,这个计数器表示常量池的个数constant-pool-count。需要注意的是,虽然在上面的表中显示,常量池的个数是16个。但是实际上只有15个是有效的常量池,constant-pool[i]表示,i的下标是从1-->constant-pool-count -1某个具体的常量池。原因是,其实正常来水就是16个,不过这个constant-pool[0]是被系统占用了。这个constant-pool[0]是系统用于指定固定的一个引用才占用的。其实实际上也是constant-pool-count个常量池。表示常量池个数也是占据两个字节。这两个字节紧跟在最大版本号的后面也就是00 16。

2.常量池存放的内容

通常情况下,常量池存放的内容是以下两类,字面量、符号引用两类

2.1字面量

字面量这个东西,就是那种现成的字符串例如“abcdsef”,或者是被final修饰的变量的值(原因是,被final修饰的值会在前置编译阶段完成赋值,因此这个10会存放在字节码文件中),总之是一眼就能看到的这种值类型的东西。

2.2符号引用

这个符号引用主要是分成三个部分分别是类的全限定名、简单名称、描述符以下进行简单叙述

  • 类或者接口的全限定名,例如org/example/jvmlearning/learning02/Demo;,这个就是类的全限定名,和全类名的区别是,用/代替了.同时最后以;结尾。
  • 简单名称,这个其实就是一堆方法名或者是属性名
  • 描述符,这个描述符主要针对的是方法和属性,方法的话是指参数类型,例如int,double等,实际写的时候写的是I,D。如果是针对方法的,描述符指的就是参数列表和方法返回值例如()V,([Ljava/lang/String;)V。

3.杂谈

.class文件中是不包含类信息的内存布局信息的,这个里面的信息就是一堆简单的符号而已。通常类的加载过程是分为加载、链接、初始化三个阶段。这个链接又可以分为验证、准备、解析三个阶段。其中,在解析阶段是完成了把常量池的符号引用转为直接引用的阶段,会把符号引用转为了实际的内存地址。使得可以访问到具体的对象或者方法等信息。