Java编译器允许使用'this'关键字访问未初始化的空白最终字段?这是一个错误吗?

sac*_*tiw 8 java final initialization javac

我写了这段代码,似乎编译器允许在使用'this'关键字访问时访问未初始化的空白最终字段:

public class TestClass
{
    public final int value1;
    public int value2;

    TestClass(int value) {
        value2 = 2 + this.value1; // access final field using 'this' before initialization gives no compiler error
        //value2 = 2 + value1;      // uncomment it gives compile time error - variable value1 might not have been initialized
        value1 = value;
    }

    public static void main(String args[]) {
    TestClass tc = new TestClass(10);
    System.out.println("\nTestClass Values : value1 =  " + tc.value1 + " , value2 =  " + tc.value2);
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试在1.5,1.6和1.7上编译它,并在所有这三个中得到相同的结果.

对我来说,它看起来像编译器错误,因为编译器必须在这种情况下抛出错误,但是它没有'this'关键字,因此会产生编码错误的范围,因为程序员不会注意到它,因为没有编译时或运行时错误将被抛出.

不足之处为什么它不是重复的
- 所有答案都在解释它是如何工作的以及JLS所说的,很好,但我真正的意图是应该在第一时间允许吗?
- 我的问题更多来自程序员的观点,而不是语言语义

Dam*_*ash 1

这不是一个错误。这是 Java 规范 1.6 及更低版本的功能。

可以在代码的任何部分访问最终字段。对此没有任何限制。

Final 的唯一限制是它必须在创建类实例之前初始化。

当您使用 时this,您表示它是正在构造的对象的元素。

自规范 1.7 以来,由于更改,我们可以说这是编译器某些实现中的错误。

但从 1.8 开始,代码将为this.value1or产生相同的错误value1

  • +1“自规范 1.7 以来,由于变化,我们可以说这是编译器某些实现中的错误。” 但无论你是否同意,也不管以前版本的 JLS 怎么说,我都将其视为一个错误,因为它让我在代码中引入了一个错误。:P (2认同)