在浏览JLS 8.3.2.3时,我无法理解以下代码。
class Z {
static { i = j + 2; }
static int i, j;
static { j = 4; }
}
代码导致错误Cannot reference a field before it is defined
但是,如果我将代码更改为
class Z {
static { i = 2; }
static int i, j;
static { j = 4; }
}
代码正在编译中。但在这两种情况下,变量定义都在初始化块之后。这背后的秘密是什么?
答案 0 :(得分:8)
您可以将分配给比其声明更早的值 - 您无法读取它。所以这也失败了:
static { System.out.println(j + 2); }
static int j;
然而这很好:
static { j = 5; }
static int j;
section 8.3.2.3中无效使用的四个条件之一是:
(该部分的双重否定让我头疼,但我认为与之相关!)
老实说,规范的那部分是我见过的最糟糕的一部分 - 它的真的不清楚。但结果是你可以分配但不能阅读:)
答案 1 :(得分:1)
实际上,它是编译器的基础,
赋值语句从从右到左执行。
e.g。i=2;
表示2分配给i,2表示常量,因此无需声明
另一方面,如果我们写
i=j+2;
它将首先编译j,然后将其分配给i,因此它会导致错误,因为j尚未定义。
答案 2 :(得分:0)
在i = j + 2;
中,您使用在不同静态块中初始化的变量j
。
你应该只在一个静态块中放置所有内容,j
初始化和表达式来编译代码。此代码有效:
public class Z {
static int i, j;
static { j = 4;
i = j + 2; }
}
的Davide