Local inner classes safe access to local variables of containing method
When defining a local inner class, is it safe to access local variables of the containing method that only said class has references to. Like so:
public Bar containingMethod()
{
Foo foo = new Foo();
Bar bar = new Bar()
{
public void baz()
{
System.out.println("Accessing foo: " + foo.getValue());
}
};
return bar;
};
In my example above I'm not sure that the class being defined has a reference to foo
. The question is if it's safe and OK to do this or am I running the risk of foo
being garbage collected before bar.baz()
is cal开发者_C百科led?
It is safe, but foo needs to be final (otherwise you should get a compile error).
Foo will not be garbage collected, because under the hood, bar will contain a reference to it.
The reason for foo needing to be final is to avoid this hidden reference getting out of sync.
From a garbage-collection standpoint, it would be safe even without foo being final. But the reference to foo that bar holds is assigned when you create bar, and never updated, so if the containing method were allowed to assign something else to foo later, bar would still see the "old" object.
Note that the requirement to be final only applies to local variables and parameters, not to instance fields of the containing class.
It's can be safe but it depends what the inner class is doing.
You need to look to consider how your inner class will use the variable. For example, if you are creating a runnable or an asynchronous task, the inner class could access the variable from another thread or even after the outer method has exited. So you may need to synchronize the object (for example) before using it to prevent inadvertent issues.
Also the variable needs to be final. This is a language restriction to prevent the inner class from changing the variable's reference at runtime. It's a bit of a pain and it would be nice if it were an implicit rather than an explicit feature of the language.
If you're doing normal things (not hacking classloaders through reflection or anything) it's perfectly safe. As others have mentioned, there's an implicit reference from the inner to the outer object (as long as the inner class is not defined static), so it won't be garbage collected.
As a rule of thumb, there's no way at all to have a handle to an object which is garbage collected through a normal reference. This is stuff you don't have to worry about (it's not c++ ;))
The only way to do it would be through a weak-reference (which is specifically made for the job) or maybe through messing with bytecode. But not in 'normal' code.
Your code doesn't compile so your question is meaningless. When you put in the required 'final' modifiers the code compiles and is safe, which is what the 'final' modifier conveys.
精彩评论