当前位置: 首页 > 科技观察

(a+b)-10,哪里有10?是常量池吗?

时间:2023-03-20 16:44:10 科技观察

今天看到一个很有意思的问题:(a+b)*10,10存放在哪里?是常量池吗?如果是常量池,则在进行计算时通过指针找到。?答:10在常量池中,jdk1.8之后常量池已经移到元空间中了。验证这个答案是否正确其实很简单。写一个测试方法,通过javap查看编译后的字节码指令,得出结论。测试方法源码如下:privateintm(inta,intb){intr=a*b*10;returnr;}使用javap查看编译后的字节码如下:privateintm(int,int);descriptor:(II)iflags:ACC_PRIVATECode:stack=2,locals=4,args_size=30:iload_11:iload_22:imul3:bipush105:imul6:istore_37:iload_38:ireturn笔者浏览了JVM字节码指令表,相关指令如图以下。字节码指令由操作码和零个或多个操作数组成。编译后会写入方法的Code属性中。操作数要么是立即数,要么是指向类文件结构常量池中常量的索引,要么是跳转目标指令的偏移量。设数字10为x,可以得出如下结论:当x的值在[-1,5]区间时,x直接编译到方法的code属性中,作为iconst指令的操作数;当x的值在[-128,127]区间时,x也被直接编译到方法的code属性中,作为bipush指令的操作数,取值范围为[-128,127],因为bipush指令只能是一个字节;当x取值在[-32768,32767]范围内时,x也被直接编译到方法的代码属性中作为sipush指令的操作数。取值范围为[-32768,32767],因为sipush指令的操作数有两个字部分;否则,x会被编译到类的常量池中,并在运行时由ldc指令从常量池(元空间)压入操作数栈。本文转载自微信公众号“爪哇艺术”,可通过以下二维码关注。转载本文请联系爪哇艺术公众号。