我想知道如何编写初始化静态类变量的 Java 字节码



我现在正在研究Java字节码。 我想编写 Java 字节码来制作 Test.java 在 java 源代码中,如下所示。 我想在类中声明和初始化静态变量。

测试.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**
}

我正在编写的代码

测试.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_1 1: 放置 #2//字段 a:I 4:返回

对不起,奇怪的英语句子。 如果你让我知道,谢谢你。

为了完整起见,静态字段的初始值设定项的行为不是编译时常量,描述为 Java 语言规范中类初始化的步骤 9:

接下来,按文本顺序执行类的类变量初始值设定项和静态初始值设定项

,或接口的字段初始值设定项,就好像它们是单个块一样。

此块是javap打印为static {},隐藏您感兴趣的实现细节。

对于这个细节,我们必须参考 Java 虚拟机规范 §2.9.2.,类初始化方法:

如果满足以下所有条件,则方法就是类或接口初始化方法

  • 它具有特殊名称<clinit>.
  • 它是void(§4.3.3(。
  • [...]该方法设置了ACC_STATIC标志,并且不带参数(§4.6(。

我省略了有关旧版 JVM 中未强制执行哪些属性的详细信息,因为您不应该利用这些缺陷。类初始值设定项应始终具有上面指定的属性。

通常,Java 虚拟机规范是您在处理 Java 字节码时应始终拥有的文档。

最新更新