我正在研究Java字节码。
我想编写Java字节码以在Java源代码中创建Test.java,如下所示。
我想在一个类中声明和初始化静态变量。
Test.java
public class Test {
public static int a=1;
public Test() {
}
public static void main(String[] var0) {
}
}
命令结果:javap -c测试
public class Test {
public static int a;
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: return
**static {};
Code:
0: iconst_1
1: putstatic #2 // Field a:I
4: return**
}
我正在编写的代码
测试
.class public Test
.super java/lang/Object
.field public static a I
.method public <init>()V
aload_0
invokenonvirtual java/lang/Object/<init>()V
return
.end method
.method public static main([Ljava/lang/String;)V
.limit stack 32
.limit locals 32
return
.end method
我使用jasmin-2.4将Java字节码转换为.class。
我想知道如何在静态{}中编写Java字节码;
码:
0:iconst_1
1:putstatic#2 //字段a:I
4:返回
对不起,奇怪的英语句子。
谢谢,如果您让我知道。
最佳答案
为了完整起见,Java语言规范中的Step 9 of the class initialization描述了静态字段(不是编译时常量)的初始化程序的行为:
接下来,以文本顺序执行类的类变量初始化器和静态初始化器,或接口的字段初始化器,就好像它们是单个块一样。
此块是javap
打印为static {}
的内容,隐藏了您感兴趣的实现细节。
有关此详细信息,我们必须参考Java虚拟机规范§2.9.2., Class Initialization Methods:
如果满足以下所有条件,则方法是类或接口初始化方法:
它具有特殊名称<clinit>
。
它是void
(§4.3.3)。
[...]该方法已设置其ACC_STATIC
标志,并且不接受任何参数(§4.6)。
我省略了有关哪些属性未在旧版JVM中强制执行的详细信息,因为您不应该利用这些缺陷。类初始化程序应始终具有上面指定的属性。
通常,the Java Virtual Machine Specification是处理Java字节码时应始终准备好的文档。
关于java - 我想知道如何编写初始化静态类变量的Java字节码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59332829/