gpt4 book ai didi

java - 为什么静态初始化 block 中的赋值编译没有错误?

转载 作者:搜寻专家 更新时间:2023-10-31 20:11:53 25 4
gpt4 key购买 nike

我在 Java 中试验初始化顺序,我遇到了一些非常令人困惑的事情:

static {
System.out.println("Static 1, staticField can't be accessed (compile error)");
staticField = "value"; // NO COMPILE ERROR!
//System.out.println(staticField); // compile error
}

public static String staticField;

static {
System.out.println("Static 2, staticField=" + staticField); // prints "value"
}

如您所见,我们无法引用尚未声明的字段,因此第一个静态 block 中 System.out.println(staticField); 的编译错误:

Cannot reference a field before it is defined.

但是,可以分配这样一个字段,正如我们从第二个静态 block 中的值可以看出的那样。

为什么会这样?

最佳答案

该行为在 JLS §8.3.2.3 - Restrictions on the use of Fields during Initialization 中列出:

The declaration of a member needs to appear textually before it is used only if the member is an instance (respectively static) field of a class or interface C and all of the following conditions hold:

  • The usage occurs in an instance (respectively static) variable initializer of C or in an instance (respectively static) initializer of C.

  • The usage is not on the left hand side of an assignment.

  • The usage is via a simple name.

  • C is the innermost class or interface enclosing the usage.

It is a compile-time error if any of the four requirements above are not met.

基本上,当您通过表达式左侧的简单名称访问 static 字段时,根据第二条规则,不应在它之前进行声明。但是,在赋值的右侧使用它,或者试图在表达式中使用它的值,则需要事先声明它,否则会出现编译错误。

换句话说,您可以为这些字段分配任何值,但不能在简单名称上使用它们的值,而这正是您在 print 语句中尝试做的。

当然,如果您使用限定名称来使用该字段,那么它就可以工作。因此,以下代码将编译:

static {
System.out.println("Static 1, staticField can't be accessed (compile error)");
staticField = "value"; // NO COMPILE ERROR!
System.out.println(Main.staticField); // compiles fine now
}

关于java - 为什么静态初始化 block 中的赋值编译没有错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22409543/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com