我正在研究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/

10-09 07:00
查看更多