Similar to variable and methods, java allows us to create a class within another class. Classes defined inside another classes are known as nested classes. This tutorial explains different details of nested classes like types of nested classes, program of nested classes, why we use nested classes, when we use nested classes etc. The basic syntax of a nested class is :
class
OuterClassName { ...class
NestedClassName { ... } }
Types of Nested classes in Java
Nested classes are divided into two categories: static and non-static. Nested classes that are declared using static
keyword
are called static
nested classes. Non-static nested classes are called inner classes. Nested classes can be divided as below :
- Non-static nested class (inner class)
- Member inner class
- Local inner class
- Anonymous inner class
- Static nested class
Does java creates different .class files for nested or inner classes ?
Yes, Java compiler creates different .class
file for outer and inner class of a program after compilation. Generally the inner class
.class
file name is made with combination of outer and inner class name with $ sign in between like OuterClassName$InnerClassName.class
Member Inner class
A class defined inside another class but outside any method or block is known as member inner class. These classes act as a member of outer class similar as member variables and methods. The basic syntax of declaring a member inner class is :
class
OuterClassName { ... access_modifierclass
MemberInnerClassName { ... } } Example :class
OuterClass { ...public
class
InnerClass { ... } }
Some of the key points about the member inner classes are :
- It can have all type of access modifiers(
public, private, protected
or default) in it's declaration. Remember, the outer most class can have onlypublic
and default(no modifier) modifier in it's declaration. - These classes can also be declared as
abstract
orfinal
. - It can access any member of the outer class, no matter whether they are
static
,private
or anything else. - These classes can only define non-static members inside it.
- Like instance variables and methods, inner classes are also associated with an instance of the outer class.
Remember a class can not be declared as abstract
and final
together, no matter whether it's an inner or outer class. We will discuss
about abstract
and final
classes in later tutorials.
How to create object of member inner class ?
Since these classes belongs to an object, you should create the object of its outer class first then create the object of inner class using the outer class object like below :
OuterClassName outer =new
OuterClassName(); OuterClassName.InnerClassName inner = outer.new
InnerClassName();
Here OuterClassName
and InnerClassName
is the name of outer and inner class respectively while outer
and inner
is the name of outer and inner class object respectively.
As you can access member variables of a class directly inside a non-static method, similarly you can directly create the object of member inner class inside a non-static method of outer class, as given
in below program inside the run
method. Remember outside the outer class, you must need the reference of outer class to create the object of member inner class.
Member inner class program in Java
class
OuterClass {int
outerVar = 100;class
MemberInnerClass {int
innerVar = 50;int
getSum(int
param) {return
innerVar + outerVar + param; } }public static void
main(String[] args) { OuterClass outer =new
OuterClass(); OuterClass.MemberInnerClass inner = outer.new
MemberInnerClass(); System.out.println(inner.getSum(10)); outer.run(); }void
run() { MemberInnerClass memberInner =new
MemberInnerClass();// Creating object directly
System.out.println(memberInner.getSum(20)); } }
Save above program as OuterClass.java
, compile as javac OuterClass.java
. Java compiler will create two .class
file,
OuterClass.class
and OuterClass$MemberInnerClass.class
for above program.
Run as java OuterClass
Output:
160
170
Local or method local Inner class
Local inner class is a class which is defined inside a method or block of outer class, like local variables. It can be defined inside
static
or non-static method. These classes are accessible within the method only,
similar as local variables. The key points about the local inner classes are :
- They cannot have access modifiers(
public, private, protected
) in their declaration. - The only modifiers that you can use with local inner class declaration are
abstract
andfinal
. - They can access any member of outer class, no matter whether they are
static
,private
or anything else. - These classes can only define non-static members inside them.
- They can access only
final
variables of it's enclosing method. Accessing non-final variables of it's enclosing methods will result in compilation error.
How to create object of local inner class ?
Creation of local inner class object is similar as creation of normal objects like below. You don't need the reference of outer class object, as local inner class belongs to method only.
LocalInnerClassName objName = new
LocalInnerClassName();
Here LocalInnerClassName
is the name of local inner class while objName
is the name of local inner class object.
Java program of local inner class
class
OuterClass {int
outerVariable = 100;static int
staticOuterVariable = 200;public static void
main(String[] args) { OuterClass outer =new
OuterClass();int
sum = outer.run(); System.out.println("Total sum = "
+ sum); }public int
run() {int
localVar = 50;final int
finalLocalVariable = 60;// Creating local inner class
class
LocalInnerClass {int
innerVariable = 20;int
getSum(int
parameter) {// Cannot access localVar here as it's not declared as final
return
outerVariable + staticOuterVariable + finalLocalVariable + innerVariable + parameter; } } LocalInnerClass local =new
LocalInnerClass();return
local.getSum(10); } }
Save above program as OuterClass.java
, compile as javac OuterClass.java
and run as java OuterClass
Output:
Total sum = 390
Anonymous Inner Class
An anonymous inner class is a class that has no name. These classes are usually declared inside a method or block, but it can be defined outside a method or block as well. They are generally used to define an implementation of interface or abstract class. It can be a re-implementation of a normal or super class as well. The key points about anonymous inner classes are :
- They cannot have access modifiers(
public, private, protected
) in their declaration. - These classes ends with a semicolon(;) after curly braces }.
- They can access any member of outer class, no matter whether they are
static
,private
or anything else. - These classes can only define non-static members inside it, not
static
members. - This is the only type of inner class that cannot define constructors since it doesn't have a name.
- These classes can be defined as a parameter inside a method as well.
How to create anonymous inner class ?
The creation of anonymous inner class is little different than normal class creation. It starts with new
keyword followed by the name of class/interface that need to be
implemented. It's similar as constructor creation except that it has a body. These classes are declared and used to create one object in a single statement. The creation of anonymous
class looks like below :
// As implementation of a class
new
ClassName() {// class body
};// Here parameters will be passed to constructor of defined ClassName.
new
ClassName(parameters) {// class body
};// As implementation of interface
new
InterfaceName() {// class body
};// Or It can be defined like below as well
ClassOrInterfaceName objName =new
ClassOrInterfaceName() {// class body
};
Here ClassName/InterfaceName/ClassOrInterfaceName
is not the name of anonymous class, it's already defined an abstract class, superclass, normal class or interface name.
Anonymous inner class program in Java
The program below defines a simple abstract
class first. The anonymous class implements this abstract class.
abstract class
MyAbstractClass {abstract void
run(); }class
OuterClass {public static void
main(String args[]) { MyAbstractClass obj =new
MyAbstractClass() {// Start of anonymous class body
int
innerVariable = 100;public void
run() { System.out.println("innerVar = "
+ innerVariable); System.out.println("Inside anonymous inner class method"
); } };// End of anonymous class
obj.run(); } }
Save above program as OuterClass.java
, compile as javac OuterClass.java
and run as java OuterClass
Output:
innerVar = 100
Inside anonymous inner class method
Static Nested class
Classes that are defined inside the class but outside any method or block using static
keyword are called static nested classes.
These classes act as static member of outer class which means these classes belongs to outer class, not the object of outer class. The key points about static nested classes are :
- It can have all type of access modifiers(
public, private, protected
or default) in it's declaration. - These classes can also be declared as
abstract
orfinal
. - It can not access non-static members of outer class directly but using outer class object it can access them.
- It can define both static and non-static members inside it's body.
- You can access these classes directly inside the containing/outer class. To access from a class outside the containing class, use the syntax
OuterClassName.StaticClassName
.
How to create object of static nested class ?
Inside the outer(enclosing) class, you can directly create the object of static nested class, but outside that, you need the outer class name to create the object of static nested class.
// Inside outer/enclosing class
StaticClassName objName =new
StaticClassName();// Outside the outer class
OuterClassName.StaticClassName objName =new
OuterClassName.StaticClassName();
Here OuterClassName
and StaticClassName
is the name of outer class and static nested class respectively while objName
is
the name of static nested class object.
Can I create object of static nested class using outer class object ?
No you can not, since these classes belongs to class(outer class) and not to an instance of the outer class, doing so will result in compilation error.
Static nested class program in Java
class
OuterClass {int
outerVariable = 50;static int
staticOuterVariable = 100;static class
StaticNestedClass {int
innerVariable = 10;int
getSum(int
parameter) {// Cannot access outerVariable here directly as it's not static
return
innerVariable + staticOuterVariable + parameter; } }public static void
main(String[] args) { OuterClass outer =new
OuterClass(); StaticNestedClass inner =new
StaticNestedClass(); System.out.println("Sum = "
+ inner.getSum(20)); outer.run(); }void
run() { StaticNestedClass inner =new
StaticNestedClass(); System.out.println("Inside run method, Sum = "
+ inner.getSum(40)); } }
Save above program as OuterClass.java
, compile as javac OuterClass.java
and run as java OuterClass
Output:
Sum = 130
Inside run method, Sum = 150
Why we use nested class in Java
There are couple of reasons for using nested classes which includes the following :
- Nesting of classes is a way of logically grouping classes that are only used in one place. If your class is useful to only one other class, then it's logical to include it in that class and keep both classes together.
- Nesting of classes helps to write more readable and maintainable code: Nesting small classes within top-level classes places the code closer to where it is used which makes easy for programmer to read and modify the code whenever required.
- Nesting also increases encapsulation. Consider classes A and B, where B needs access to members of A which needs to be declared as
private
. By hiding class B within class A, A's members can be declaredprivate
and B can access them. Furthermore, B itself will be hidden from the outside world.
When to use nested classes in Java
When you know that your class is going to be used by one class only or your class will act as a helper class to it's outer class, you should make your class as inner class. Moreover if you know that
the existence of your class is dependent on one other class only, declare your class as inner class inside that class.
In java, HashMap
class contains number of inner classes like KeySet
, EntrySet
,
Node
etc which acts as helper class to HashMap
class.
- A nested class can have another nested class inside it.
- Nesting of classes can be done any number of time, however doing more than one level of nesting is not a good design as it increases complexity.
- You can define different types of nested classes together inside a class.
- Nested classes except anonymous class can extend/implement other classes or interfaces as well.
- Anonymous class internally extends/implements implemented class/interface.
- Using anonymous class object you can access variables and methods of implemented class/interface only. Any new variable or method defined inside anonymous class won't be accessible by it's object.
- Members of all nested classes can have any access modifiers in their declaration.
- You can also define nested class inside an interface.