【问题标题】:why is accessing a default value of final variable allowed only via a method when it is not allowed with simple access为什么只允许通过简单访问的方法访问最终变量的默认值
【发布时间】:2018-03-09 06:08:51
【问题描述】:

我浏览了很多关于堆栈溢出的帖子,试图找出为什么下面的代码 1 不起作用,但代码 2 可以。 我发现在第 6 版和第 7 版中不同版本的行为或编译器存在不一致,如帖子https://stackoverflow.com/questions/13864464/use-of-uninitialized-final-field-with-without-this-qualifier 所示。这更多地与访问带有或不带有“this”的默认最终变量有关。然而,根据我的理解,在 jls 8 规范中,这一点在前两行中非常清楚 here

我还了解到,不允许访问尚未明确直接初始化的最终变量(通过简单名称)(代码 1)。但是在方法中访问时同样有效(代码 2)。我使用 jdk 1.8.0.141 编译这些代码 sn-ps,运行后得到代码 2 的输出,如图所示。

我想知道通过方法访问最终变量是如何产生这种差异的。是不是因为在这种情况下使用 this 访问变量(隐式由于方法调用)。如果是这样,为什么在代码 1 中使用 'this.x' 而不是 'x' 不起作用。

代码 1:

class Test {
    final int x;
    {
        System.out.println("Here is x " + x);  // x replaced with this.x also does not work
        x = 7;
        printX();
    }
    Test() {
        System.out.println("const called");
    }
    void printX() {
        System.out.println("Here x is " + x);
    }
    public static void main(String[] args) {
        Test t = new Test();
    }
}

不编译:变量 x 可能尚未初始化。 (this.x 也一样)

代码 2:

class Test {
    final int x;
    {
        printX();
        x = 7;
        printX();
    }
    Test() {
        System.out.println("const called");
    }
    void printX() {
        System.out.println("Here x is " + x);
    }
    public static void main(String[] args) {
        Test t = new Test();
    }
}

这符合并给出(在不同的行上)

这里 x 是 0 这里 x 是 7 常量调用

PS : 代码来源于here

【问题讨论】:

  • 我不确定为什么这个问题没有得到答案或任何评论。如果它太长,我可以缩短它,实际上就问题而言,准确地说,它从最后一段开始。如果不清楚或过于冗长,请告诉我

标签: java this variable-assignment final


【解决方案1】:

在与我的一些朋友分享这个问题后,我得到了一个指向此堆栈溢出帖子的链接here

虽然公认的答案似乎是在谈论一个完全不同的前向引用概念。 这是@Tunaki 的第二个答案, 根据我的理解,这是正确的答案。它还在 jls 8 中为section 16.2.2提供了正确的参考

【讨论】:

    猜你喜欢
    • 2013-12-27
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 2011-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多