There are some topics on Stack Overflow on the compiler error Cannot refer to a non-final variable message inside an inner class defined in a different method
and the solution is "declare it as final and you're done", but with this theoretical question I would like to inspect what is the logical reason why this code cannot compile:
private void updateStatus(String message) {
Runnable doUpdateStatus = new Runnable() {
public void run() {
/* do something with message */
}
}
/* do something with doUpdateStatus, like SwingUtilities.invokeLater() */
}
(solution: declare message
as final) whereas this one does:
private String enclosingClassField;
private void updateStatus() {
Runnable doUpdateStatus = new Runnable() {
public void run() {
/* do something with enclosingClassField */
}
}
/* do something with doUpdateStatus, like SwingUtilities.invokeLater() */
}
I'm really confused. enclosingClassField
is not final, it can change every time many times, whereas the poor message
argument of updateStatus
can only change within its method body, and is instead blamed by the compiler ;)
Even the compiler error is misleading to me. Cannot refer to a non-final variable message inside an inner class defined in a different method
: Different from what? Isn't message
defined in the same method as the inner class? Isn't enclosingClassField
instead defined outside the method? Uhm...
Can someone point me to the correct interpretation of this matter? Thanks.