When thinking about inner classes in java, the first thing that comes to my mind is that, WHY do we need to add inner classes to normal one? Leave alone all the specific details of the Java syntax, I think the reason is quite SIMPLE: we are human beings and we are always looking for approaches with LESS effort to get things done. In a word, we are lazy and sometimes laziness can boost our technology to an unprecedented extend.
Access Control
Inner classes in Java have special access privileges from the scope in which they are defined. They can access all the fields of the outer class including date that would otherwise be private. So when it comes to the situation in which ONE class need to access some private data in another class and the private data are ONLY visible to this class, we'd better use inner class. Instead, we will need to define an access method of the outer class for the use of only one class. It is not worthwhile.
Then the question comes to HOW could the inner classes access fields of the outer class.
It's important to know that, the access control behavior is done by the compiler, not the virtual machine. In the virtual machine's perspective, the inner class and the outer one are two distinctive classes. With compilation, the inner class holds the reference of the outer one and the outer class adds special access methods implicitly. In the default constructor of the inner class, the reference of the outer class is passed to a filed added by the compiler in this way the inner class could know which instance it is bounded. Also, we can write the inner object constructor more explicitly, using the syntax:
outerObject.new InnerClass(construction parameters);
Local Inner Classes
The important thing that distinguishes local inner classes to normal ones is that, local inner classes are defined in the scope of a function. And local classes are never declared with access specifier (public/private) because they do not need one. They are only used in the scope of the function in which they are defined and they are totally hidden from the outer world, they are not visible even to other functions in the outer class.
There is another advantage of Java inner class: they can even access local variables which are defined final. The fact why the local variable should be defined final is that, the class gets the value in construction and if the value changed, it may cause some kind of conflicts. If you really need to change the var value in the inner class, you can define the local var to be an array which means the reference to which can never be changed while the value it holds can be modified.
Anonymous Inner Classes
If we only need one instance of a class, we can use anonymous class which we do not need to specify a name for it. In Swing, we often create a new object of a class that implements the ActionListener interface.
Static Inner Classes
If we do not need the inner class hold the reference of the instance of the outer class, we use static classes. Only inner classes can be defined static.
Reference:
1. Core Java Vol 1. 8th edition. Page:258-295.