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

问题描述 投票:0回答:1

我正在研究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 bytecode
1个回答
0
投票

为了完整起见,静态字段的初始化程序的行为不是编译时常量,在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中强制执行的详细信息,因为您不应该利用这些缺陷。类初始化程序应始终具有上面指定的属性。

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

© www.soinside.com 2019 - 2024. All rights reserved.