Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
An Introduction into the concept of nested classes in Java
Overview
This article is going to shed some lights on the concepts of the implementation of the nested classes in Java in a simple and easy to comprehend manner. The various types of nested classes are explained with some examples that explain their usage and advantage over normal top-level-classes.
Concepts
One of the nice and highly advantageous features of Java is the ability to define nested classes, i.e. classes within classes. In java classes are either top-level-classes (classed defined directly within a package) or nested classes (classes defined within top-level-classes). One might wonder in regard to why all this complication is even helpful, and whether or not such classes bring any advantage to the java programmers at all.
Well, during the time I’ve spent exploring the what’s ad why’s of Java’s nested classes, I’ve realized two important, but distinct, advantages to that, and these are:
Nested classes types and basic examples
Nested classes in java can be classified into the following types, each exhibit a slightly different behaviors than each other, which might limit their use to a specific particular case:
public class OuterClass
{
private int private_member_variable = 100;
public class InnerClass
{
public void printPrivateVariable()
{
System.out.println(private_member_variable);
}
}
public void callInnerClassMethod()
{
InnerClass innerClass = new InnerClass();
innerClass.printPrivateVariable();
}
public static void main(String args[])
{
OuterClass outerClass = new OuterClass();
outerClass.callInnerClassMethod();
}
}
It is very important to state that the instance of the Inner class doesn’t exist in isolation, rather it is bounded by and associated with an instance of their enclosing top-level-class, and this impose a slight restriction on the inner nested classes which is that they can’t have any static members that normal top-level and static nested classes can. the following code excerpt depicts that concept and how an instance of the Inner class can be obtained from code outside their enclosing class:
public class TestClass
{
public static void main(String args[])
{
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.printPrivateVariable();
}
}
The following code excerpt shows how to define anonymous classes from within top-level-classes:
public class Test
{
public static void main(String args[])
{
Runnable runnable = new Runnable()
{
public void run()
{
}
};
}
}
Anonymous inner classes come in handy when an object instance are required on the fly that extends a certain class or implement a certain interface without the need to write a complete top-level-class for that. The situations where anonymous inner classes are beneficial can be envisaged when the need arise for a Runnable class to be passed to a Thread (as the above code excerpt shows) or when an event listener implementation need to be passed to register for certain event occurrence in event-driven development environments. The syntax for defining anonymous inner classes can be broken down into the following:
new Interface to implement | abstract/concrete class to extend () {body of the anonymous class to be defined};
public class OuterClass
{
private int private_member_variable = 100;
public static class StaticInnerClass
{
public void printPrivateVariables()
{
OuterClass outerClass = new OuterClass();
System.out.println(outerClass.private_member_variable);
}
}
public static void main(String args[])
{
StaticInnerClass staticInnerClass = new StaticInnerClass();
staticInnerClass.printPrivateVariables();
}
}
To obtain an instance of a static nested class from within code defined outside the enclosing class, one needs to follow the normal instance creation mechanism in java as the static class exist in isolation from their enclosing class and they are not associated with any instance of their enclosing class:
public class Test
{
public static void main(String args[])
{
OuterClass.StaticInnerClass staticInnerClass = new OuterClass.StaticInnerClass();
staticInnerClass.printPrivateVariables();
}
}