Regardless, though, I need my inner class to be non-static, because each instance of it needs to invoke non-static methods that use it's non-static instance data.
In that case, the outer objects shouldn't be garbage collected ... because the outer objects are where that instance data resides!
FOLLOWUP
What would you recommend then? I have no idea how use packages, but I need to create instances of Inner which have public data fields accessible only to Outer
, and can survive past the destruction of Outer
. Am I out of luck?
Before I answer your question:
- "I have no idea how use packages ..." - you ought to learn about them then. Packages and "package private" access are an important part of the Java language.
Now to your question ...
If you want fields only to be accessible to the Outer
class (and classes nested within) then you have to use nested or inner classes. (If you try to do this using a package and package-private access, then other classes declared in the same package can also access the fields. However, if that's acceptable, then packages are a simpler way to do this.)
Assuming that you are going to do this using nested or inner classes, then there are two ways to do this:
If you declare the Inner
class as private static class Inner
, then methods in the Inner
class CANNOT call instance methods or access instance fields of Outer
... unless they have a reference to and Outer
instance (e.g. passed as a parameter). If Inner
is static
, the lifetime of instances of Inner
and Outer
are independent.
If you declare the Inner
class as private class Inner
, then methods in the Inner
class CAN call instance methods or access instance fields of Outer
. But the flip side is that the lifetime of an Outer
instance and its Inner
instances are now dependent. Specifically, an Outer
instance will exist as long as at least one of its Inner
instances continues to exist. (The reverse is not true ... unless the Outer
instance is holding references for Inner
instances in (say) a collection-typed field.)
Just to restate what I said previously. If an Inner
instance needs to access instance fields or call instance methods on an Outer
instance, then it needs an explicit or reference to that Outer
instance. That means that the Outer
instance is reachable, and is not a candidate for deletion by the garbage collector.
The other point is an instance of Inner
won't go away if it is still reachable; i.e. if some part of your running application has a reference to the instance that it could possibly use. In Java, objects DON'T get garbage collected if there is any possibility that they could be used by the running application. Instances of inner/nested classes are not special in this regard.
Actually, there may be a (really nasty!) way to do it break the linkage between the Inner
and Outer
instances. If you can find all of the Inner
instances, you can use reflection to assign null
to the this$0
hidden variable in each one. However, if you do that, any code in the Inner
class that refers to the Outer
instance state will break. If you are going to resort to this kind of nastiness, you are better off declaring Inner
as a static
class.