Consider following example :
public class OuterClass {
private AnonymousInnerClass anonymousInnerClass = new AnonymousInnerClass() {
@Override
protected void printAboutme() {
System.out.println("AnonymousInnerClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
};
public void displayAnonymousInnerClass() {
anonymousInnerClass.printAboutme();
}
public void displayStaticInnerClass() {
NestedStaticClass staticInnerClass = new NestedStaticClass();
staticInnerClass.printAboutMe();
}
public void displayInnerClass() {
InnerClass innerClass = new InnerClass();
innerClass.printAboutMe();
}
public void displayMethodInnerClass(){
class MethodInnerClass {
private String sampleField = "Method Inner Class";
public void printAboutMe() {
System.out.println("MethodInnerClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
}
MethodInnerClass methodInnerClass = new MethodInnerClass();
methodInnerClass.printAboutMe();
}
class InnerClass {
private String sampleField = "Inner Class";
public void printAboutMe() {
System.out.println("InnerClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
}
abstract class AnonymousInnerClass {
protected String sampleField = "Anonymous Inner Class";
protected abstract void printAboutme();
}
static class NestedStaticClass {
private String sampleField = "NestedStaticClass";
public void printAboutMe() {
System.out.println("NestedStaticClass.printAboutMe.........");
Class clazz = this.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String message = Modifier.isPublic(field.getModifiers()) ? "public":(Modifier.isPrivate(field.getModifiers())?"private":"protected");
message = message + " " + field.getType().getSimpleName();
message = message + " " + field.getName();
System.out.println(message);
}
}
}
}
in this example there is comparison of every type of non static nested class with static nested class.Now if you run display method of Outer class for each nested class you will see output of each nested class printAboutMe() method,which has some reflection code to print all the member variables of nested classes.
You will see for non nested classes there is one extra member variable other than declared variable string in code,which is only present at run time.
for instance if we execute following code for InnerClass. :-
public class NestedClassesDemo {
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
outerClass.displayInnerClass();
}
}
output is like this :-
InnerClass.printAboutMe.........
private String sampleField
protected OuterClass this$0
Note there is mystery member variable this$0 of type enclosing class(Outer class).
Now you are clear that inner classes keep reference to outer class.So image scenario where you pass reference of inner class to other outer world class and then reference never gets released to in turn OuterClass is also referenced , hence leak.
So this makes using inner classes bad if not used prpperly.
There not such case with static inner classes.Please run all display methods.Also if any problem in code please do point out.