特殊方法的方法名
首先要明确一下, 这里的特殊方法是指的类的构造方法和类型初始化方法。
构造方法就不用多说了, 至于类型的初始化方法, 对应到源码中就是静态初始化块。 也就是说,
静态初始化块, 在class文件中是以一个方法表述的, 这个方法同样有方法描述符和方法名,具体如
下:
- 类的构造方法的方法名使用字符串 表示
- 静态初始化方法的方法名使用字符串 表示。
- 除了这俩种特殊的方法外,其他普通方法的方法名,喝源文件种的方法名相同。
总结
- 方法和字段的描述符中, 不包括字段名和方法名, 字段描述符中只包括字段类型, 方法描述
符中只包括参数列表和返回值类型。 - 无论method()是静态方法还是实例方法,它的方法描述符都是相同的。尽管实例方法除了传递
自身定义的参数,还需要额外传递参数this,但是这一点不是由方法描述符来表达的。参数this
的传递,是由Java虚拟机实现在调用实例方法所使用的指令中实现的隐式传递。
常量池在class文件中的什么位置?
CA FE BA VE -> 副版本号 -> 主版本号 -> 常量池计数器 ->常量池
常量池的里面是怎么组织的?
cp_info:常量池项
constatnt_pool_count:常量池计算器
常量池的结构是什么?
常量池数据区
常量池(cp_info)表示的范围
常量池项(cp_info)-> 字面量 ->文本字符串;
常量池项(cp_info)-> 字面量 ->被声名为final的常量值;
常量池项(cp_info)-> 字面量 ->基本数据类型的值;
常量池项(cp_info)-> 字面量 ->其他;
常量池项(cp_info)-> 符号引用 ->类喝结构的完全限定名;
常量池项(cp_info)-> 符号引用 ->字段的名称和描述符;
常量池项(cp_info)-> 符号引用 ->方法的名称和描述符;
String类型的字符串常量在常量池中是怎样表示和存储的?
对于字符串而言,JVM会将字符串类型的字面量以UTF-8编码格式存储到class字节码文件中。这么说可能有点转向,从直观的java源码中出现的用双引号“”括起来的字符串来看,在编译器编译的时候,都会将这些字符串转换成CONSTANT_String_info结构体,然后放置于常量池中。
将Java源码编译成StringTest.class文件后,在此文件的目录下执行 javap -v StringTest 命令,
会看到如下的常量池信息的轮廓:
(PS :使用javap -v 指令能看到易于我们阅读的信息,查看真正的字节码文件可以使用HEXWin、
NOTEPAD++、UtraEdit 等工具。)
在面的图中,我们可以看到CONSTANT_String_info结构体位于常量池的第#15个索引位置。而存
放"Java虚拟机原理" 字符串的 UTF-8编码格式的字节数组被放到CONSTANT_Utf8_info结构体中,该
结构体位于常量池的第#16个索引位置。上面的图只是看了个轮廓,让我们再深入地看一下它们的组织
吧。请看下图:
由上图可见:“JVM原理”的UTF-8编码的数组是:4A564D E5 8E 9FE7 90 86,并且存入了
CONSTANT_Utf8_info结构体中。
总结
- 对于某个类或接口而言,其自身、父类和继承或实现的接口的信息会被直接组装成
CONSTANT_Class_info常量池项放置到常量池中; - 类中或接口中使用到了其他的类,只有在类中实际使用到了该类时,该类的信息才会在常量池中有
对应的CONSTANT_Class_info常量池项; - 类中或接口中仅仅定义某种类型的变量,JDK只会将变量的类型描述信息以UTF-8字符串组成
CONSTANT_Utf8_info常量池项放置到常量池中,上面在类中的private Date date;JDK编译器
只会将表示date的数据类型的“Ljava/util/Date”字符串放置到常量池中。