【问题标题】:Static block structure changing after compilation编译后静态块结构发生变化
【发布时间】:2020-08-29 20:54:35
【问题描述】:

我在静态块之后声明了一个静态变量。当我调用一个方法打印它的值时,结果为0。我反编译了.class文件,发现静态块的结构发生了变化。谁能解释一下为什么?

class Testing {
static {
    callMe();
    System.out.println("Static finished");
}
static void callMe() {
    System.out.println(x);
}
static int x = 10;
public static void main(String[] args) {
    System.out.println("Complete");
}}

反编译代码:

class Testing {
static int x;

Testing() {
}

static void callMe() {
    System.out.println(x);
}

public static void main(String[] args) {
    System.out.println("Complete");
}

static {
    callMe();
    System.out.println("Static finished");
    x = 10;
}}

【问题讨论】:

标签: java static jvm static-methods static-block


【解决方案1】:

如果总体结果相同,则允许编译器重新排序执行。

在您的情况下是这样,因为static 块和初始化程序是按声明的顺序执行的,所以static int x = 10; 的内联赋值在之后执行打印。

至于为什么你的确切编译器版本以它的方式重新排序你的代码是编译器开发团队的一个问题。

【讨论】:

  • 我给 x 赋值了 10,不应该打印吗?
  • 否 - 静态内容按声明的顺序执行,因此分配值 10 发生在 打印之后。请参阅编辑后的答案。
  • 是的,当我看到反编译的代码时,这很好。但是为什么我的表达式分成两部分,初始化变成了静态方法呢?
  • 就像我说的,编译器可以根据需要重新排列代码。可能有一些微优化的原因。
  • 没有进行重新排序和优化。编译后的类文件中只有一个静态块。反编译器根本不知道这段代码分布在原始源代码的不同部分。
猜你喜欢
  • 2014-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-15
  • 1970-01-01
相关资源
最近更新 更多