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

try/catch语句中有效final变量的赋值

燕鸿波
2023-03-14

以下代码不能用javac 1.8.0_144和ECJ编译:

private LongSupplier foo() {
    long fileSize;
    try {
        fileSize = canThrow();
    } catch (IOException e) {
        fileSize = 42;
    }

    LongSupplier foo = () -> 1 + fileSize;
    return foo;
}

>

  • 声明为最终。

    在赋值表达式(§15.26)中,它从不作为左手边出现。(请注意,包含
    初始值设定项的局部变量声明符不是赋值表达式。)

    它从不作为前缀或后缀递增或递减运算符的操作数出现(§15.14,§15.15)。

    它从不作为前缀或后缀递增或递减运算符的操作数出现。

    方法、构造函数、λ或异常参数(§8.4.1,§8.8.1,§9.4,§15.27.1,§14.20)为了
    确定它是否有效地是最终的,被视为一个局部变量
    ,其声明符有一个初始值设定项。

    我的理解是,在子句2中,try/catch块中的赋值是允许的,因为在赋值之前filesize肯定是未赋值的。

    我认为解释代码被拒绝的理由是:

    • filesize在try块之前明确未分配
    • fileSize是在fileSize=canThrow()
    • 之后分配的(肯定吗?似乎16.1.8不关心分配中的异常)
    • filesize在try块之后分配
    • FileSize在catch块之前并不是绝对未赋值的,因此在catch块中的赋值之前也不是绝对未赋值的。
    • 因此,4.12.4中的第2条不适用于此处

    这是正确的吗?

  • 共有1个答案

    鄢英毅
    2023-03-14

    “有效final”的定义表明,添加final修饰符不应更改任何内容。让我们这样做,得到一个更清楚的错误:

    error: variable fileSize might already have been assigned
                        fileSize = 42;
                        ^
    

    因此,这与使用try/catch进行Final变量赋值完全相同(它也提供了使用第二个Final变量的变通方法),即变量出现在赋值的左边,这意味着它不一定是未赋值的。

     类似资料:
    • 因此,我开始使用Java8streams/lambda表达式,遇到了一些有趣的问题,我不知道如何解决这些问题。所以我在这里,请求你的帮助。 现在我得到编译器错误“在lambda表达式中使用的变量应该有效地是final”。 怎么做? 方法createNewDocument和createOldDocument引发异常,因此调用必须在try/catch块内。我还需要关闭finally块内的文档。

    • 因为我相信这是一个很好的编程实践,所以如果我的所有(局部或实例)变量只需要编写一次,我就将它们设为< code>final。 但是,我注意到当变量赋值可以抛出异常时,您不能将所述变量设为最终变量: 有没有办法在不诉诸临时变量的情况下做到这一点?(或者这不是最终修饰符的正确位置?)

    • 问题内容: 我正在审查一些新代码。该程序仅具有try和finally块。由于不包含catch块,如果try块遇到异常或任何可抛出的异常,它将如何工作?它是否直接进入了finally块? 问题答案: 如果try块中的任何代码都可以引发已检查的异常,则它必须出现在方法签名的throws子句中。如果引发了未经检查的异常,则该异常会冒泡退出方法。 无论是否引发异常,都始终执行finally块。

    • 在实际开发中,根据 try catch 语句的执行过程,try 语句块和 catch 语句块有可能不被完全执行,而有些处理代码则要求必须执行。例如,程序在 try 块里打开了一些物理资源(如数据库连接、网络连接和磁盘文件等),这些物理资源都必须显式回收。 Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只回收堆内存中对象所占用的内存。 所以为了确保一定能回收 try 块中打开的物理资源,异

    • 我刚刚开始用java编写一个21点游戏。我试图让程序要求用户再次输入,如果他们输入的现金不是一个有效的整数。我看到许多带有catch的try语句示例,但没有一个是有效的。程序给出的错误InputMismatchException无法解析为类型。我遵循的一个线程就是这个,我有完全相同的代码,只是变量名不同。给你。Java输入不匹配异常 这是我的密码: 任何关于为什么我几乎精确的代码不起作用的帮助都将

    • 我很确信在这里 如果控制到达捕获块,不可能已经被分配了。但是,Java编译器不同意并声称。 我在这里是否仍然缺少一些微妙之处,或者这只是Java语言规范用于识别潜在重新分配的模型的弱点?我主要担心的是像这样的东西,这可能会导致异常被“凭空”抛出,但我仍然不明白如何在分配后抛出它,这显然是尝试块中的最后一个操作。 如果允许的话,上面的习惯用法会使我的许多方法变得更简单。注意,这个用例在语言中有一流的