In Java, it is possible to define a class within another class. Class defined within another Class is called a Nested Class.
Nested class is treated as a member of the Outer class because it is also defined within the Outer class like its other members(variables or methods).
public class OuterClass {
class NestedClass {
}
}
Although Outer class can be declared only either as public or package private(no access modifier) but Nested classes can have any of the access modifier public, private, protected or package private(no access modifier), reason being , nested class is also just like a member of the Outer class, so just like you can have public, private ,protected or package private instance variables or methods, you can have these access modifiers for nested classes as well.
Now if you define your nested class as static, then they are called static nested class and if you don't define them as static then they are called non static nested classes or Inner classes. So Nested classes are broadly of two types :
- Static Nested Classes
- Inner Classes
In this post, we will discuss static nested classes.
Static Nested Class :
They are just like any other Java class which are defined with a static modifier within a Outer class for the packaging convenience and from packaging convenience I mean that instead of creating another top level class we packaged this nested class within another class as this nested class made sense only in the context of enclosing Outer class. We will see example later.
public class OuterClass {
public static class NestedClass {
}
}
Rules for static nested class as a static member of Outer class
Rules for instantiating static nested class
Because static nested classes are static ,so just like the static methods and variables they follow the rules which static members within a class follows. So just like static methods and variables, they belong to their Outer class and not to the instance(s) of the Outer class. So you don't need to instantiate OuterClass first but you just use <outer class><dot><nested class> syntax to instantiate the nested classes as in below example.
public class TestClass {
public static void main(String[] args) {
OuterClass.NestedClass nestedClass = new OuterClass.NestedClass();
}
}
Rules for accessing the Outer class members from static nested class
Static nested class being static, can only access the static members of its outer class. It does not have access to the instance members of the Outer class. This makes sense again, if you think just from static perspective. Any static method of our class in general can only access the static variables or static methods only, so the same concept is applied for static nested classes as well, because they are also the static members of the Outer class from Outer class perspective.
public class OuterClass {
private static String x;
private String y;
public static class NestedClass {
public void test() {
// x is accessible
System.out.println(x);
// y is not accessible here and it will give compiler time error
// "No static field 'y' can not be referenced from static context.
System.out.println(y);
}
}
}
You might have noticed that test() method itself is not static but still the compiler warning says "can not be referenced from static context", this is because although test() method is not a static method but still the class in which it has been defined as , is static, so from OuterClass perspective "y" which is not a static member of OuterClass is being referred from within it's static member NestedClass.
Other than that from its own existence perspective, they are just like any normal Java classes, which means :
- You can create their objects(By using <OuterClass><dot><NestedClass> syntax).
- You can have instance variables within them.
- You can have instance methods within them.
- You can have static methods in them.
- You can extend them.
- You can declare them final.
Only difference from top level java class is that it can be declared static and it can have any of the access modifier which means public, package private, protected or private.
So to conclude this section, you need to see static nested classes from two perspective :
- As a static member of the Outer class and rules for accessing it(nested class) being a static member And rules for accessing Outer class members.
- As a normal Java class which is just packaged within another class.
What is the use of Static nested Classes ?
1. Packaging Convenience and as Helper classes
In general, we use nested class when the class is not required to be used anywhere else other than in the class it is part of. For example we can define helper classes using nested static classes. And if they need to be accessed also from within Outer class only, we can declare static nested class as private, so that it is invisible to the outside world.
For example:
1. If we see java.util.Collections class in JDK, you can find lots of private nested classes like:
SetFromMap
ReverseComparator
CopiesList
As these classes serve only to Collections class, are not being used from anywhere else in JDK and does not use any instance variable or method of the outer Collection class, they have been kept as private and nested static classes.
2. Static nested classes specially should be used(instead of inner classes) when you don't want to use enclosing class's instance members in nested class but want to keep Outer class and Nested class together for packaging convenience. For example, in the
Builder Pattern that we discussed in one of previous post, Builder is created as static nested class. This builder does not use/call any of the Outer class instance variable/method but as we know that this builder makes sense only in context of Student class, so we packaged Student and its builder together.
And we can instantiate this static nested builder without using the instance of the Outer class as below:
Student.StudentBuilder studentBuilder2 = new
Student.StudentBuilder("2", "Sachin", "Tendulkar").withAge("47");
3. They are very useful for creating Request and Response type of classes for your restful services as you can easily map them to the Json structure.
public class Employee {
private String name;
private String age;
public static class Address {
private int houseNumber;
private String streetName;
}
}
2. Better Readability and Maintainability
It leads to more readable and maintainable code because you keep closely used classes together at one place instead of spreading it across in multiple top level classes.
Summary
- Nest a class inside another class as a static nested class, when the class you are going to write is going to be used only within that class or in its context.
- Make it static because you don't need access to the instance members of Outer class. If you need access then go for Inner classes.
- Only nested classes can be declared as static. Top level classes can not be declared as static.
- Static nested classes can be declared public, protected, package private or private. Top level classes can only be public or package private.
- If a static nested class is declared as public, but Outer class is package private, then you can access nested class also within that package only because static nested class can only be accessed by using class name of the Outer class and if Outer class is not visible then static nested class will not be visible even if it is public.
- Nested static classes are like static members of the Outer class and follows the rules of static within Outer class.
- Use them as helper classes for better readability or for request response for rest service.
Thank you for reading. If you any question or suggestion to add further in this post, you can let me know in comments section.