当前位置: 首页 > 知识库问答 >
问题:

为什么只允许通过方法访问最终变量的默认值,而简单访问不允许

何峰
2023-03-14

我已经阅读了许多关于堆栈溢出的文章,试图找出为什么下面的代码1不起作用,但代码2起作用。我发现在6版和7版的不同版本中,行为或编译器存在不一致性https://stackoverflow.com/questions/13864464/use-of-uninitialized-final-field-with-without-this-qualifier.这更多地涉及访问默认的最终变量,无论是否有“This”。然而,在jls 8规范中,根据我的理解,这一点在这里的前两行中非常清楚

我还了解到,访问一个还没有明确初始化的final变量(通过简单的名字)是不允许的(代码1)。但是在一个方法中访问时(代码2),情况完全相同。我使用JDK 1.8.0.141来编译这些代码片段,运行后我得到了代码2的输出,如图所示。

我想知道通过方法访问最终变量是如何产生这种差异的。这是因为在这种情况下,变量是使用此方法访问的(隐式地由于方法调用)。如果是,为什么要用这个。代码1中的“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可能尚未初始化。(这个也一样. 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 : 代码最初是从这里获取的

共有1个答案

韦志新
2023-03-14

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

虽然公认的答案似乎是在谈论一个完全不同的前瞻性参考概念。这是@Tunaki的第二个答案,根据我的理解,这是正确的答案。它也在jls 8中给出了16.2.2节的正确参考。

 类似资料:
  • 问题内容: 我了解为什么编译器不接受以下内容: 让我感到困惑的是,编译器接受以下内容,并且单元测试通过了: 为什么上述方法有效并且可以正常工作?欢迎使用指向JLS相关部分的指针(15.27.2节仅讨论局部变量)。 问题答案: 我们都同意第一个例子不能用,因为局部变量或参数必须是最终的或有效的最终才能在lambda表达式主体中使用。 但是您的第二个示例不涉及局部变量或参数,而是实例字段。Lambda

  • 我理解为什么编译器不接受以下内容: 令我困惑的是编译器接受以下内容,并且单元测试通过了: 为什么上面的是有效的,工作正常?欢迎提供JLS相关章节的链接(第15.27.2节。只谈局部变量)。

  • 问题内容: 我指着一些窍门,发现了这一点。在以下代码中: 对象是。为什么这段代码没有抛出? 我知道这不是访问变量的正确方法,但问题在于。 问题答案: 如果要使用以下方法反汇编您的班级文件,请向当前答案中添加一些其他信息: 你会得到: 在这里,您可以看到该指令在第7行完成了对静态字段的访问。每当通过代码访问静态字段时,都会在程序文件中生成相应的指令。 指令具有特殊性,即它们不需要在调用它们之前就对要

  • 本文向大家介绍PHP 只允许指定IP访问(允许*号通配符过滤IP),包括了PHP 只允许指定IP访问(允许*号通配符过滤IP)的使用技巧和注意事项,需要的朋友参考一下 核心函数代码如下: 在需要检测的地方 加上调用 check_ip(); 即可;  本函数提供只允许指定的IP访问文件,并提供IP中*号通配符 匹配多IP 

  • 以下是JDK11的源代码: 使用访问器而不是直接使用字段有什么意义?既然访问器方法是最终的,为什么不声明:并删除访问器呢?

  • 问题内容: 我看到以下错误: 使用此代码: 是什么原因引起的,如何解决? 问题答案: 在当前域之外发出ajax请求时,Javascript是受限制的。 例1:您的域名为example.com,并且您想向test.com提出请求=>您不能。 例2:您的域名是example.com,并且您想向inner.example.com发送请求,但是您不能。 例3:您的域名为example.com:80,并且您