Java静态初始化块上的奇怪代码

Dun*_*ter 3 java static initializer jls

通过JLS 8.3.2.3时,我无法理解以下代码.

class Z {
static { i = j + 2; }
static int i, j;
static { j = 4; }
}
Run Code Online (Sandbox Code Playgroud)

代码导致错误 Cannot reference a field before it is defined

但是,如果我将代码更改为

class Z {
static { i = 2; }
static int i, j;
static { j = 4; }
}
Run Code Online (Sandbox Code Playgroud)

代码正在编译中.但在这两种情况下,变量定义都在初始化块之后.这背后的秘密是什么?

Jon*_*eet 8

您可以在声明之前分配一个值 - 您无法读取它.所以这也失败了:

static { System.out.println(j + 2); }
static int j;
Run Code Online (Sandbox Code Playgroud)

这很好:

static { j = 5; }
static int j;
Run Code Online (Sandbox Code Playgroud)

第8.3.2.3节中无效使用的四个条件之一是:

  • 用法不在作业的左侧.

(该部分的双重否定让我头疼,但我认为这很重要!)

说实话,这部分规格是我见过的最糟糕的一部分 - 它真的不清楚.但结果是你可以分配但不读:)