I am updating various swing components using the event dispatching thread. However when I do something like the following I get an error –
public Foo(User user) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
getNameTextField.setText(user.getName());
}
});
}
The error is – “local variable user is accessed from within inner class; needs to be declared final”
What is the standard solution to this…just put final before each function parameter?
Now obviously I dont want to declare my actual user object final as I might need to modify it in future. But is it ok to just set final on the user object in the function parameter?
But what am I actually doing when I set that to final as that is a reference to the ‘main’ user object in my program. So the same object is declared final in one place, yet not final in another. Does declaring it final simply mean the reference to it is final, however the user object itself can be modified freely?
The solution is to make the function arguments final as you suggest.
The final modifier means that the reference cannot be reassigned after the first assignment. It confers no guarantees on the referred object.
btw, This is an artefact of the way anonymous inner classes were ‘bodged’ into the language. The compiler creates hidden fields for each of the arguments, if you decompile your code above you can see what’s going on…
In the decompilation below you see that a new class Foo$1 is created (foo method #0) and at line #6 it is passed the User arg in it’s constructor. You’ll see similar shenanigans going on in the decompilation of Foo$1.class sigh
Compiled from “Foo.java”
Compiled from “Foo.java”
Here’s my Foo.java (your’s didn’t compile…)