我正在研究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**
}
我正在编写的代码
Test.j
.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_11:putstatic#2 //字段a:I4:返回
对不起,奇怪的英语句子。谢谢,如果您让我知道。
为了完整起见,静态字段的初始化程序的行为不是编译时常量,在Java语言规范中以Step 9 of the class initialization描述:
接下来,以文本顺序执行类的类变量初始化器和静态初始化器,或接口的字段初始化器,就好像它们是单个块一样。
此块是javap
打印为static {}
的内容,隐藏了您感兴趣的实现细节。
关于这个细节,我们必须参考Java虚拟机规范,§2.9.2., Class Initialization Methods:
方法是类或接口初始化方法,如果以下所有条件均成立:
我省略了有关哪些属性未在旧版JVM中强制执行的详细信息,因为您不应该利用这些缺陷。类初始化程序应始终具有上面指定的属性。
通常,Java虚拟机规范是在处理Java字节码时应始终准备好的文档。