Ilias Koutsakis

About 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.

Java Nested (Inner) Class Example

In this example we are going to explain what exactly nested classes are 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 a nested class 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. Nested Classes 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

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

// 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

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

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:

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 code

This was an example of nested classes in Java.
You can download the code here: NestedClassExample

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.
Examples Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Examples Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close