Static Member Classes

In this post I will tell you everything about Static Member Classes from inside out. You must have been frustrated by remembering about the rules governing Inner Classes. In this post I will tell you how Inner Classes actually work. This will help you get a deep knowledge of Inner Classes which will help you a lot. This code will tell how the compiler changes the Inner Classes. But remember, that is a some difference in the code given here and what is generated by the compiler. This article uses a simplified approach by removing and modifying some of the code generated by the compiler.
Static Member Classes can also be called as Static Inner Classes. To begin with let me tell you in brief about Static Member Classes.

They can be declared inside top-level classes or other Static Member Classes

These are declared within other classes with the static modifier.

They can declare static and non-static members.

All accessibility modifiers can be used with these classes.

To create an object of Static Member Class, you don’t need an instance of its enclosing class.

An instance of enclosing class is not stored in an instance of a Static Member Class.

They can access static members of the enclosing class including private static members.

They can access non-static members of the enclosing class(including private non-static members) on an object of the enclosing class.

The reverse is also correct i.e. members of the enclosing class can access static members of the Member Class directly and non-static members of the Member Class on an Object of the Member Class.

If you are astonished by the above list of information, don’t worry. In the course of this tutorial, you will come across all these facts.
Now let’s begin one by one how the compiler changes different types of codes in an inner class. By the end you will know completely how all the code in an inner class is transformed to make the inner class a normal top level class.

First lets see how an inner class accesses static members of the enclosing class by their names.

Now when you compile the program the compiler converts the class Inner to a normal top level class. But now the question arises that what will happen to Statement # 8. Well the answer is simple, the compiler adds the name of the enclosing class i.e. Outer before the name of the variable a. So after compilation, the program given above will look like this-

Note the name of the member(inner) class after compilation. The compiler adds the name of the enclosing class before the name of the member class seperated by a $. The static keyword is also gone as top-level classes cannot be static. To access the member class from any code outside the enclosing class, you have to use the syntax <enclosingClassName>.<memberClassName>. So to access the class Inner from outside the class Outer you will have to use the name of the class as Outer.Inner.
Now you know that members of a class can access private members of the class. So a member class can also access the private members of the enclosing class. But how can the member class access private members of the enclosing class after compilation. Since after compilation the member class is converted into a normal top-level class, so it has no direct access to the private members of the enclosing class. But the compiler creates some package visible methods to make this possible.

Now after compilation the class Inner will become a top-level class. At Statement # 8 the compiler adds a method call since this statement tries to access a private member of the enclosing class. Lets see how this happens-

Look how cleverly the compiler generates a method at Statement # 4 which has access to private members of the class. This method returns the value of the static field a. Notice the ugly name of the compiler generated method. You cannot explicitly call this method in your code because the compiler will flag it as an error. If a local declaration or a field in the inner class or its super class hides the field of the enclosing class, you can access the field by placing the name of the enclosing class before the field name. It goes like this-

Now that you know everything about how a Static Member Class can access all the static members of the enclosing class, lets see how the static member class accesses the non-static members of the enclosing class on an object of the enclosing class.

There is no problem in the Statement # 10 as it accesses a non-private member of the enclosing class. There is nothing wrong with it. But Statement # 11 tries to access a private member of the enclosing class. This is how it is made possible after compilation-

In this case the compiler generates a static package visible method at Statement # 5 which takes an object of the enclosing class as parameter. Statement # 16 accesses the private non-static member of the enclosing class by calling this method and sending the instance of the enclosing class as argument. The method returns the value of the field on the object passed to it.
Till now you have only seen how to access the value of fields from an Inner Class. But you can also mutate i.e. set the value of fields and make method calls. The example below shows you how this happens for non-private members-

The compiler adds the name of the class Outer before the field and method names at Statements # 18, 19 and 20. This is the only change made by the compiler (apart from making the class Inner a top level class). Its easy enough! But if what we are trying to access is private member of the enclosing class, then the code becomes a bit complicated. Lets see how you can mutate the values of private fields of the enclosing class-

For Statement # 9 the compiler will generate a static package visible method that takes the value that you set with the assignment. For Statement # 11 the compiler generates another static package visible method that takes the object of the class Outer and the value that you assign to the field. These methods are shown at Statements # 5 and 9 in the code below-

For both these methods, the compiler generates static package visible methods which inturn calls these methods which are unavailable to the inner class after compilation. The methods generated by the compiler for the mehods and their call are shown in the code below-

The methods at Statements # 11 and 15 call the methods getCube() and getProduct() respectively. The methods calls at Statements # 24 and 27 are generated by the compiler. The original calls are shown in comments. Lets see the opposite of this i.e. accessing the private members of the inner class from the members of the enclosing class.

Note that I have used the name Outer.Inner to represent the inner class in the enclosing class at Statements # 6, 8 and 10. This is just to avoid any confusion as the name Outer.Inner must be used to represent the inner class from any code outside the enclosing class. There is one last thing that you must note before we move to Non Static Member Classes. If you don’t access some members of the enclosing class from the inner class then the compiler doesn’t generates methods for them. For Example-

The code above will not be altered much by the compiler. Since the field a is not accessed in the inner class so no method will be generated for that. So the code after compilation will look like this-