You probably use inner classes which are (if I refer to Wikipedia):
In object-oriented programming, an inner class (aka nested class) is a class declared entirely within the body of another class or interface. It is distinguished from a subclass.
In Java, we can illustrate this concept with this sample:
public final class Clazz { private final class InnerClazz implements Runnable { public InnerClazz() { } @Override public void run() { System.out.println("Hello world"); } } public Clazz() { } public Runnable getRunnable(){ return new InnerClazz(); } }
It’s a simple sample that does nothing useful but the declaration of inner classes is shown. I remark that the difference between nested classes and inner classes is not always understood by every developer.
Inner class
The previous code declares a nested class “InnerClazz”. A new instance of it is created each time the getRunnable method is called. If you analyze this code with FindBugs, you will have this warning:
SIC: Should be a static inner class (SIC_INNER_SHOULD_BE_STATIC)
This class is an inner class, but does not use its embedded reference to the object which created it. This reference makes the instances of the class larger, and may keep the reference to the creator object alive longer than necessary. If possible, the class should be made static.
The message is explicit: an inner class keeps a reference on its parent class and so, as long as the InnerClazz is referenced, the parent class can’t be garbage collected (there’s a strong reference between the inner class and its parent -> you may read on memory management). This kind of nested class is useful when you want to use the reference:
public final class Clazz { private final class InnerClazz implements Runnable { public InnerClazz() { } @Override public void run() { // print the value of a member of its "parent" class // it's possible because the inner class has an implicit reference // on the Clazz instance System.out.println(_currentNumber); } } private int _currentNumber = 0; public Clazz() { } public Runnable getRunnable() { _currentNumber++; return new InnerClazz(); } }
Nested but not inner class
If you don’t need to keep a strong reference between the instance of Clazz and InnerClazz, just declare InnerClazz as a static member class (now called NestedNotInnerClazz).
public final class Clazz { // static keyword is added static private final class NestedNotInnerClazz implements Runnable { public NestedNotInnerClazz() { } @Override public void run() { System.out.println("Hello world"); } } public Clazz() { } public Runnable getRunnable(){ return new NestedNotInnerClazz(); } }
Yes, it’s easy…
Comments 4
“I remark that the difference between static inner classes and standard inner classes is not always understood by every developer.”
I remark that you don’t understand the difference between static inner classes and non-static inner classes. The former does not exist while the latter does
You have confused nested classes with inner classes. See JLS Section 8.
Posted 08 Sep 2009 at 9:59 am ¶Hello Tony,
Posted 08 Sep 2009 at 10:38 am ¶Oh… Sorry for the confusion and you’re right. Thank you for your comment, it helps me. I’ve just checked the JLS. I’ll make the correction soon.
For other readers, I put a first correction here:
Both of the classes that I described here are nested classes.
A nested class but not inner is what I called “static inner class”.
An inner class is a kind of nested class. I called it “non-static inner classes”. They can be local, anonymous or non-static member classes.
As you see, I put the wrong names but the concepts are there. I make the correction as soon as possible.
Thank you Tom.
Coderfriendly
No worries mate
Posted 08 Sep 2009 at 10:39 am ¶Correction done.
Posted 08 Sep 2009 at 10:51 am ¶Post a Comment