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.