java - Java 字节码 - 为什么要跳过偏移量?
问题描述
我有这个非常简单的课程
public class TestImpl2 {
public TestImpl2() {
}
public double run(double param) {
double d = 7.0D;
double k = 4.0D;
if (param < k) {
System.out.println(d);
}
return 0.0D;
}
}
我用 javac 编译然后用 javap 反编译以查看它的字节码。
0: ldc2_w #14 // double 7.0d
3: dstore_3
4: ldc2_w #16 // double 4.0d
7: dstore 5
9: dload_1
10: dload 5
12: dcmpg
13: ifge 23
16: getstatic #23 // Field java/lang/System.out:Ljava/io/PrintStream;
19: dload_3
20: invokevirtual #29 // Method java/io/PrintStream.println:(D)V
23: dconst_0
24: dreturn
让我们检查偏移量
0 - 为“this”引用保留
1 - 是方法参数
2 - 跳过?
3 - 变量“d”
4 - 跳过?
5 - 变量“k”
为什么跳过了偏移量 2 和 4?是因为方法参数、d 和 k 是双精度数还是完全不同?
解决方案
根据JVM规范(强调我的):
局部变量通过索引来寻址。第一个局部变量的索引为零。当且仅当该整数比局部变量数组的大小小 0 到 1 之间时,整数才被认为是局部变量数组的索引。
type
long
或 type的值double
占用两个连续的局部变量。这样的值只能使用较小的索引来解决。例如,存储在索引 n 处的局部变量数组中的 double 类型的值实际上占用了索引为 n 和 n+1 的局部变量;但是,不能从中加载索引 n+1 处的局部变量。
并不是不使用索引 2 和 4。就是这样,param
并且d
是double
s,它们每个占据 2 个空间。
推荐阅读
- python - 覆盖numpy数组中的像素
- java - 从工作区中删除未使用的 java 类可以提高 Web 服务器的性能?
- terminal - ZSH 提示在超级终端上以百分号开头
- asp.net - 将反应客户端谷歌登录转移到 ASP.NET 服务器端
- r - 比较 R 中的答案和解决方案(即比较两个表格)
- java - 多线程Android应用中组件应该如何交互?
- tensorflow - 如何实现keras中提出的tree-lstm,树结构是如何构建的?
- c - 如何在while循环中检测用户输入是[ Control ] + [ D ]
- java - 如何制作一个包含另一个数组的随机元素对的二维数组?
- python - 如何使用此功能从列表中删除重复项?