看一下下面的代码:
class Foo{
public static int x = 1;
}
class Bar{
public static void main(String[] args) {
Foo foo;
System.out.println(foo.x); // Error: Variable 'foo' might not have been initialized
}
}
当试图通过一个未初始化的本地变量Foo foo;
访问静态字段x
时,foo.x
会产生编译错误:Variable 'foo' might not have been initialized.
这个错误似乎是有道理的,但只有当我们意识到JVM在访问static
成员时实际上并没有使用变量的值,而是只用它的类型时,才能理解。
例如,我可以用null
值初始化foo
,这将使我们可以无任何问题地访问x
:
Foo foo = null;
System.out.println(foo.x); //compiles and at runtime prints 1!!!
这种情况可行是因为编译器认识到 x
是静态的,并将 foo.x
视为像 Foo.x
那样书写(至少在我之前是这么想的)。
那么为什么编译器突然坚持要求 foo
有一个值,而实际上它将完全不会使用呢?
声明:这不是真正应用中会使用的代码,而是我找不到在Stack Overflow上的答案的有趣现象,所以我决定询问。
static
成员变量,编译器不使用变量的值而是使用其类型。 我们甚至可以编写((Foo)null).x
,这将编译并工作,因为编译器将识别出x
是静态的(除非我误解了你的评论)。 - Pshemofoo.x
)应该被编译器报错。但可惜的是,这艘船已经在25年前启航,并且如果现在改变它,将会导致破坏性的变化。 - PowerlordFoo.x
是首选(这就是为什么我们通常在尝试使用变体foo.x
时会得到编译警告)。 - Pshemo