gpt4 book ai didi

java - try/catch 语句中有效最终变量的赋值

转载 作者:行者123 更新时间:2023-11-30 06:46:11 27 4
gpt4 key购买 nike

以下代码不能用 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;
}

我想知道这是否是编译器中的错误。 The definition of effectively final in the JLS是:

Certain variables that are not declared final are instead considered effectively final:

  • A local variable whose declarator has an initializer (§14.4.2) is effectively final if all of the following are true:

    • It is not declared final.

    • It never occurs as the left hand side in an assignment expression (§15.26). (Note that the local variable declarator containing the
      initializer is not an assignment expression.)

    • It never occurs as the operand of a prefix or postfix increment or decrement operator (§15.14, §15.15).

  • A local variable whose declarator lacks an initializer is effectively final if all of the following are true:

    • It is not declared final.

    • Whenever it occurs as the left hand side in an assignment expression, it is definitely unassigned and not definitely assigned before the assignment; that is, it is definitely unassigned and not definitely assigned after the right hand side of the assignment expression (§16 (Definite Assignment)).

    • It never occurs as the operand of a prefix or postfix increment or decrement operator.

  • A method, constructor, lambda, or exception parameter (§8.4.1, §8.8.1, §9.4, §15.27.1, §14.20) is treated, for the purpose of
    determining whether it is effectively final, as a local variable
    whose declarator has an initializer.

我的理解是,在第 2 条中,try/catch block 中的赋值是允许的,因为 fileSize 在赋值之前肯定是未赋值的。

我认为解释拒绝代码的原因是:

  • fileSize 在 try block 之前绝对未分配
  • fileSize = canThrow()后赋值(肯定?好像16.1.8不关心赋值异常)
  • fileSize 在 try block 之后赋值
  • fileSize 在 catch block 之前不是绝对取消分配的,因此在 catch block 中的分配之前也不是绝对取消分配的。
  • 因此,4.12.4 的第 2 条不适用于此处

这是正确的吗?

最佳答案

“Effectively final”的定义指出,添加 final 修饰符不应改变任何内容。让我们这样做并得到更清晰的错误:

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

所以这与 Final variable assignment with try/catch 完全相同(这也给出了使用第二个 final 变量的解决方法),即变量出现在赋值的左侧,这意味着它并非绝对未赋值。

关于java - try/catch 语句中有效最终变量的赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47942407/

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