Core Java

Java Inner (Nested) Class Example

In this example, we are going to explain what inner or nested class is in Java. We are going to present the different categories of nested classes and their sub-types, as well as ways to use them in your program.

1. What is an inner class in Java and why you should care

Java is a very modular language, in the sense that everything is inside a class. No matter the size of the program, you need at least one class which will contain the public static void main(String[] args) method. For modularity and cleanness, every class is supposed to be implemented inside its own file, named after the class itself, e.g. ClassName.java.

However, Java allows you to  create classes not contained in their own file, but instead declared inside the body of another class, and these are called nested classes. Depending on the where and how they are implemented, they fall into a specific sub-category. Why should you use a nested class though? As stated in the official Java specification, there are several reasons to do so:

  • Logical grouping of classes that are used in one place only: As a developer you know when a class is supposed to be used in a certain way/place. By using nested classes you keep the code tight, and logically consise. Some people could argue that it is also more object-oriented that way, since small objects that are logically inside a larger one, should not be implemented somewhere else.
  • It increases encapsulation: In many cases there are two integrated classes, where class B needs access to information stored privately in class A. by declaring B as a nested class we avoid this problem.
  • It leads to more readable code: By avoiding the excess of unnecessary files created by many smaller classes, we have more maintainable and readable code, with logical and clear relations.

2. Nested class types

Let’s take a look at the different types of nested classes. We are going to have a short overview of where and how they are used, and provide more details in the code section, where the example will make clear how to implement them.

  • Static Nested Classes: These are the statically declared nested classes. Their behavior is the same as a top-level class, and we can instantiate it by itself without having to instantiate the outer class.
  • Inner (non-static) classes: These classes have 3 different sub-categories, which are:
    • Member classes: These are the classes that are defined as a member of the outer class. We need to instantiate the outer class and then instantiate the inner class itself, either using a method of the outer class, or by using new (in a slightly different way that we are going to show in the example).
    • Local classes: These classes are defined and used inside a block of code (in Java that means somewhere between braces, e.g. in a method). The most important feature of these classes is that they can only be used inside that block of code, but they can also access the members of the outer class.
    • Anonymous Inner Classes: These are classes that are declared and instantiated at the same time, usually by creating an instance of an interface (which would otherwise not be possible, as interfaces need to be implemented by another class and their methods don’t have any functionality by themselves).

3. Java Inner (Nested) Class Example

In this code example we will present and explain how to declare, implement and use the different types of nested classes that we explained in the previous section.

OuterClass.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class OuterClass {
 
    private String name;
     
    public OuterClass(String name) {
        this.name = name;
    }
     
    public void outerClassPrint() {
        System.out.println("A new outer class, with name: " + name);
    }
     
     
    // Here we create an inner class. Since the inner class is considered a member
    // of the outer class, it can be instantiated in the useual way.
    public void createAndAccessInnerClass() {
        InnerClass inner = new InnerClass();
        inner.printOuterClassName();
    }
     
    // The inner class declaration and implementation.
    // As stated in the article, it has access of all the outer class members
    // even the private ones.
    public class InnerClass {
         
        // Case in point: we access and print the name of the outer class
        // which is private.
        public void printOuterClassName() {
            System.out.println("Accessing outer class with name: " + name);
        }
    }
}

This is an outer class which contains a member class in it. We exemplify the connection between the inner class and the outer class here, by:

  • Having a method that creates an instance of the inner class and accessing its method.
  • Showing that the inner class has access to the private members of the outer class without a public accessor.

AnonymousClassInterface.java

1
2
3
4
5
// An interface which usually needs to be implemented by another class.
// In this case however, we are going to use it to create an anonymous inner class.
public interface AnonymousClassInterface {
    public void printAnonymousClass();
}

This is the interface that will be used for the anonymous inner class example. It only has one method that will be implemented during the instantiation of the class.

OuterWithStaticInner.java

01
02
03
04
05
06
07
08
09
10
11
public class OuterWithStaticInner {
     
    // By defining the inner class as static, we can access its methods
    // without outer class instantiation.
    public static class InnerClass {
         
        public void printStaticInnerClass() {
            System.out.println("A new static inner class!");
        }
    }
}

This is an example of a static inner class. We will not need to instantiate the outer class, but instead we will instantiate the inner class only.

NestedClassExampleMain.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class NestedClassExampleMain {
     
    // We can create an inner class locally in a method. In this case here,
    // we have a method which contains both the declaration and the implementation
    // of the inner class. So we can instantiate it, and access every method we need,
    // but ONLY in the scope of this method.
    public static void createLocalInnerClass() {
         
        class LocalInnerClass {
            public void printLocalInnerClass() {
                System.out.println("A new local inner class!");
            }
        }
         
        // Instantiation and use inside the method.
        LocalInnerClass local = new LocalInnerClass();
        local.printLocalInnerClass();
    }
 
    public static void main(String[] args) {
         
        // We instantiate the outer class, in order to be able to instantiate/access
        // the inner class.
        OuterClass outer = new OuterClass("Outer Class");
        outer.outerClassPrint();
         
        // 1st way of accessing the inner class: we instantiate it inside the outer class,
        // and we access it by using a method of the outer class.
        outer.createAndAccessInnerClass();
         
        // 2nd way of accessing the inner class: We instantiate it OUTSIDE of the main
        // class, and we access its methods ourselves. Since it is an inner class however,
        // we need to make it clear that it is considered a member of the outer class,
        // and this is why we use OuterClass.InnerClass in the declaration.
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.printOuterClassName();
 
        // We create the local class here.
        createLocalInnerClass();
         
        // Instead of using the interface by implementing it in another class,
        //we create an anonymous inner class here and use it without a problem.
        AnonymousClassInterface anonymous = new AnonymousClassInterface() {
 
            @Override
            public void printAnonymousClass() {
                System.out.println("A new anonymous inner class!");
            }
        };
         
        anonymous.printAnonymousClass();
         
         
        // Static Inner Class example: We instantiate only the inner class,
        // and from there we use it as any other top-level class.
        OuterWithStaticInner.InnerClass staticInner = new OuterWithStaticInner.InnerClass();
        staticInner.printStaticInnerClass();
    }
}

You can see here that the various types of nested classes are instantiated and accessed in their own unique ways.

Output

1
2
3
4
5
6
A new outer class, with name: Outer Class
Accessing outer class with name: Outer Class
Accessing outer class with name: Outer Class
A new local inner class!
A new anonymous inner class!
A new static inner class!

4. Download the source code

This was an example of inner or nested class in Java.

Download
You can download the code here: Java Inner (Nested) Class Example

Last updated on May 5th, 2020

Ilias Koutsakis

Ilias has graduated from the Department of Informatics and Telecommunications of the National and Kapodistrian University of Athens. He is interested in all aspects of software engineering, particularly data mining, and loves the challenge of working with new technologies. He is pursuing the dream of clean and readable code on a daily basis.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Priya
6 years ago

This tutorial gives you the concepts of nested classes in the Java programming language along with code examples. Very Informative , Thanks for sharing.

Back to top button