为什么Java中的局部变量不被认为是"有效的最终",即使之后没有任何修改它?

Ran*_*ku' 8 java lambda final java-8

在一个方法中我有这个:

int x = 0
if (isA()) {
    x = 1;
} else if (isB()) {
    x = 2;
}

if (x != 0) {
    doLater(() -> showErrorMessage(x)); // compile error here
}

// no more reference to 'x' here
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它会产生编译错误.错误表明这x不是最终的或有效的,因此无法从lambda主体访问它.xdoLater调用之后没有修改,因此在调用x时实际上已经确定了值doLater.

我猜这个问题的答案是因为x没有资格被称为有效最终变量.但是,我想知道原因是什么.

编译器不能只创建一个临时的最终变量,有效地使代码如下:

if (x != 0) {
    final int final_x = x;
    doLater(() -> showErrorMessage(final_x));
}
Run Code Online (Sandbox Code Playgroud)

一切都还行吗?

Pet*_*rey 14

有效的最后意味着它可以被制造,final即它永远不会改变.这意味着有效地,变量可以是一个变量final.

问题是它没有跟踪你最后一次更改它,而是你是否曾经改变它.将您的if陈述更改为

int x;
if (isA()) {
    x = 1;
} else if (isB()) {
    x = 2;
}  else {
    x = 0;
}
Run Code Online (Sandbox Code Playgroud)

要么

int x = isA() ? 1 : 
        isB() ? 2 : 0;
Run Code Online (Sandbox Code Playgroud)