(Translated by https://www.hiragana.jp/)
Inner Class in Java - GeeksforGeeks
Open In App

Inner Class in Java

Last Updated : 27 Aug, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Save
Share
Report
News Follow

In Java, inner class refers to the class that is declared inside class or interface which were mainly introduced, to sum up, same logically relatable classes as Java is object-oriented so bringing it closer to the real world. Now geeks you must be wondering why they were introduced? 

There are certain advantages associated with inner classes are as follows:

  • Making code clean and readable.
  • Private methods of the outer class can be accessed, so bringing a new dimension and making it closer to the real world.
  • Optimizing the code module.

We do use them often as we go advance in java object-oriented programming where we want certain operations to be performed, granting access to limited classes and many more which will be clear as we do discuss and implement all types of inner classes in Java.

Types of Inner Classes

There are basically four types of inner classes in java.

  1. Nested Inner Class
  2. Method Local Inner Classes
  3. Static Nested Classes
  4. Anonymous Inner Classes

Let us discuss each of the above following types sequentially in-depth alongside a clean java program which is very crucial at every step as it becomes quite tricky as we adhere forwards.

Type 1: Nested Inner Class 

It can access any private instance variable of the outer class. Like any other instance variable, we can have access modifier private, protected, public, and default modifier. Like class, an interface can also be nested and can have access specifiers. 

Example 1A

Java
// Java Program to Demonstrate Nested class 

// Class 1
// Helper classes
class Outer {

    // Class 2
    // Simple nested inner class
    class Inner {

        // show() method of inner class
        public void show()
        {

            // Print statement
            System.out.println("In a nested class method");
        }
    }
}

// Class 2
// Main class
class Main {

    // Main driver method
    public static void main(String[] args)
    {

        // Note how inner class object is created inside
        // main()
        Outer.Inner in = new Outer().new Inner();

        // Calling show() method over above object created
        in.show();
    }
}

Output
In a nested class method

Note:  We can not have a static method in a nested inner class because an inner class is implicitly associated with an object of its outer class so it cannot define any static method for itself. For example, the following program doesn’t compile. But Since JAVA Version 16 we can have static members in our inner class also.

Example 1B

Java
// Java Program to Demonstrate Nested class 
// Where Error is thrown

// Class 1
// Outer class
class Outer {

    // Method defined inside outer class
    void outerMethod()
    {

        // Print statement
        System.out.println("inside outerMethod");
    }

    // Class 2
    // Inner class
    class Inner {

        // Main driver method
        public static void main(String[] args)
        {

            // Display message for better readability
            System.out.println("inside inner class Method");
        }
    }
}

Output:


An interface can also be nested and nested interfaces have some interesting properties. We will be covering nested interfaces in the next post.

Type 2: Method Local Inner Classes 

Inner class can be declared within a method of an outer class which we will be illustrating in the below example where Inner is an inner class in outerMethod().

Example 1

Java
// Java Program to Illustrate Inner class can be
// declared within a method of outer class 

// Class 1
// Outer class
class Outer {

    // Method inside outer class
    void outerMethod()
    {

        // Print statement
        System.out.println("inside outerMethod");

        // Class 2
        // Inner class
        // It is local to outerMethod()
        class Inner {

            // Method defined inside inner class
            void innerMethod()
            {

                // Print statement whenever inner class is
                // called
                System.out.println("inside innerMethod");
            }
        }

        // Creating object of inner class
        Inner y = new Inner();

        // Calling over method defined inside it
        y.innerMethod();
    }
}

// Class 3
// Main class
class GFG {

    // Main driver method
    public static void main(String[] args)
    {

        // Creating object of outer class inside main()
        // method
        Outer x = new Outer();

        // Calling over the same method
        // as we did for inner class above
        x.outerMethod();
    }
}

Output
inside outerMethod
inside innerMethod

Method Local inner classes can’t use a local variable of the outer method until that local variable is not declared as final. For example, the following code generates a compiler error. 

Note: “x” is not final in outerMethod() and innerMethod() tries to access it.

Example 2

Java
class Outer {
   void outerMethod() {
      int x = 98;
      System.out.println("inside outerMethod");
      class Inner {
         void innerMethod() {
            System.out.println("x= "+x);
         }
      }
      Inner y = new Inner();
      y.innerMethod();
   }
}
class MethodLocalVariableDemo {
   public static void main(String[] args) {
      Outer x=new Outer();
      x.outerMethod();
   }
}

Output
inside outerMethod
x= 98

Note: Local inner class cannot access non-final local variable till JDK 1.7. Since JDK 1.8, it is possible to access the non-final local variable in method local inner class. 

But the following code compiles and runs fine (Note that x is final this time) 

Example 3

Java
class Outer {
   void outerMethod() {
      final int x=98;
      System.out.println("inside outerMethod");
      class Inner {
         void innerMethod() {
            System.out.println("x = "+x);
         }
      }
      Inner y = new Inner();
      y.innerMethod();
   }
}
class MethodLocalVariableDemo {
    public static void main(String[] args){
      Outer x = new Outer();
      x.outerMethod();
    }
}

Output
inside outerMethod
x = 98

The main reason we need to declare a local variable as a final is that the local variable lives on the stack till the method is on the stack but there might be a case the object of the inner class still lives on the heap. 
Method local inner class can’t be marked as private, protected, static, and transient but can be marked as abstract and final, but not both at the same time.

Type 3: Static Nested Classes

Static nested classes are not technically inner classes. They are like a static member of outer class. 

Example

Java
// Java Program to Illustrate Static Nested Classes

// Importing required classes
import java.util.*;

// Class 1
// Outer class
class Outer {

    // Method
    private static void outerMethod()
    {

        // Print statement
        System.out.println("inside outerMethod");
    }

    // Class 2
    // Static inner class
    static class Inner {

        public static void display()
        {

            // Print statement
            System.out.println("inside inner class Method");

            // Calling method inside main() method
            outerMethod();
        }
    }
}

// Class 3
// Main class
class GFG {

    // Main driver method
    public static void main(String args[])
    {

        // Calling method static display method rather than an instance of that class.
        Outer.Inner.display();
    }
}

Output
inside inner class Method
inside outerMethod

Type 4: Anonymous Inner Classes 

Anonymous inner classes are declared without any name at all. They are created in two ways. 

  • As a subclass of the specified type
  • As an implementer of the specified interface

Way 1: As a subclass of the specified type 

Example:

Java
// Java Program to Illustrate Anonymous Inner classes 
// Declaration Without any Name  
// As a subclass of the specified type

// Importing required classes
import java.util.*;

// Class 1
// Helper class
class Demo {

    // Method of helper class
    void show()
    {
        // Print statement
        System.out.println(
            "i am in show method of super class");
    }
}

// Class 2
// Main class
class Flavor1Demo {

    //  An anonymous class with Demo as base class
    static Demo d = new Demo() {
        // Method 1
        // show() method
        void show()
        {
            // Calling method show() via super keyword
            // which refers to parent class
            super.show();

            // Print statement
            System.out.println("i am in Flavor1Demo class");
        }
    };

    // Method 2
    // Main driver method
    public static void main(String[] args)
    {
        // Calling show() method inside main() method
        d.show();
    }
}

Output
i am in show method of super class
i am in Flavor1Demo class

In the above code, we have two classes Demo and Flavor1Demo. Here demo act as a super-class and the anonymous class acts as a subclass, both classes have a method show(). In anonymous class show() method is overridden.

Way 2: As an implementer of the specified interface  

Example:

Java
// Java Program to Illustrate Anonymous Inner Classes
// Declaration Without Any Name
// As an implementer of Specified interface

// Interface
interface Hello {

    // Method defined inside interface
    void show();
}

// Main class
class GFG {

    // Class implementing interface
    static Hello h = new Hello() {
      
        // Method 1
        // show() method inside main class
        public void show()
        {
            // Print statement
            System.out.println("i am in anonymous class");
        }
    };

    // Method 2
    // Main driver method
    public static void main(String[] args)
    {
        // Calling show() method inside main() method
        h.show();
    }
}

Output
i am in anonymous class

Output explanation:

In the above code, we create an object of anonymous inner class but this anonymous inner class is an implementer of the interface Hello. Any anonymous inner class can implement only one interface at one time. It can either extend a class or implement an interface at a time.

Explanation

In Java, an inner class is a class that is defined inside another class. An inner class can access the members of the outer class, including private members, and it can be used to implement callbacks and event handlers. There are four types of inner classes in Java:

Member Inner Class: It is a non-static class that is defined at the member level of a class. It has access to all the members of the outer class, including private members.

Local Inner Class: It is a class that is defined inside a method or a block of code. It has access to the final variables of the method or block in which it is defined.

Anonymous Inner Class: It is a class that is defined inline and has no name. It is used to implement interfaces or extend classes without creating a separate class.

Static Nested Class: It is a static class that is defined inside another class. It does not have access to the non-static members of the outer class.

Inner classes have several advantages:

Encapsulation: Inner classes can be used to encapsulate implementation details of a class, making the code more modular and maintainable.

Access Control: Inner classes can access private members of the outer class, allowing for more precise control over the visibility of members.

Callbacks and Event Handlers: Inner classes can be used to implement callbacks and event handlers, making it easier to handle events in graphical user interfaces.

Code Organization: Inner classes can be used to organize code by grouping related classes together.

Program

Java
public class OuterClass {
    private int outerVar;

    public OuterClass(int var) {
        outerVar = var;
    }

    public void outerMethod() {
        System.out.println("This is an outer method");
    }

    // Inner class
    public class InnerClass {
        private int innerVar;

        public InnerClass(int var) {
            innerVar = var;
        }

        public void innerMethod() {
            System.out.println("This is an inner method");
        }

        public void accessOuterVar() {
            System.out.println("Outer variable from inner class: " + outerVar);
        }
    }

    public static void main(String[] args) {
        // Create an instance of the outer class
        OuterClass outer = new OuterClass(10);

        // Create an instance of the inner class
        OuterClass.InnerClass inner = outer.new InnerClass(20);

        // Access the inner class methods
        inner.innerMethod();
        inner.accessOuterVar();
    }
}

Output
This is an inner method
Outer variable from inner class: 10

In this example, we have an outer class OuterClass that has an inner class InnerClass. The inner class has its own methods and variables, and it can also access the outer class’s methods and variables.

To create an instance of the inner class, we first create an instance of the outer class, and then use it to create the inner class. We can then access the inner class’s methods and also the outer class’s methods and variables using the inner class’s instance.

The benefits of using inner classes in Java are:

Encapsulation: Inner classes can access private variables and methods of the outer class. This helps to achieve encapsulation and improves code readability.

Code Organization: Inner classes allow you to group related code together in one place. This makes your code easier to understand and maintain.

Better Access Control: Inner classes can be declared as private, which means that they can only be accessed within the outer class. This provides better access control and improves code security.

Callbacks: Inner classes are often used for implementing callbacks in event-driven programming. They provide a convenient way to define and implement a callback function within the context of the outer class.

Polymorphism: Inner classes can be used to implement polymorphism. You can define a class hierarchy within the outer class and then create objects of the inner classes that implement the different subclasses.

Reduced Code Complexity: Inner classes can reduce the complexity of your code by encapsulating complex logic and data structures within the context of the outer class.

Overall, the use of inner classes can lead to more modular, maintainable, and flexible code.



Previous Article
Next Article

Similar Reads

Java - Inner Class vs Sub Class
Inner Class In Java, one can define a new class inside any other class. Such classes are known as Inner class. It is a non-static class, hence, it cannot define any static members in itself. Every instance has access to instance members of containing class. It is of three types: Nested Inner ClassMethod Local Inner ClassAnonymous Inner Class Genera
3 min read
Diamond operator for Anonymous Inner Class with Examples in Java
Prerequisite: Anonymous Inner Class Diamond Operator: Diamond operator was introduced in Java 7 as a new feature.The main purpose of the diamond operator is to simplify the use of generics when creating an object. It avoids unchecked warnings in a program and makes the program more readable. The diamond operator could not be used with Anonymous inn
2 min read
Local Inner Class in Java
Prerequisites: Nested Classes in Java Local Inner Classes are the inner classes that are defined inside a block. Generally, this block is a method body. Sometimes this block can be a for loop or an if clause. Local Inner classes are not a member of any enclosing classes. They belong to the block they are defined within, due to which local inner cla
5 min read
Anonymous Inner Class in Java
Nested Classes in Java is prerequisite required before adhering forward to grasp about anonymous Inner class. It is an inner class without a name and for which only a single object is created. An anonymous inner class can be useful when making an instance of an object with certain "extras" such as overriding methods of a class or interface, without
7 min read
Difference between Anonymous Inner Class and Lambda Expression
Anonymous Inner Class:It is an inner class without a name and for which only a single object is created. An anonymous inner class can be useful when making an instance of an object with certain "extras" such as overloading methods of a class or interface, without having to actually subclass a class.Anonymous inner classes are useful in writing impl
3 min read
How to Access Inner Classes in Java?
In Java, inner class refers to the class that is declared inside class or interface which were mainly introduced, to sum up, same logically relatable classes as Java is purely object-oriented so bringing it closer to the real world. It is suggested to have adequate knowledge access the inner class, first create an object of the outer class after th
3 min read
Output of Java program | Set 15 (Inner Classes)
Prerequisite :- Local inner classes , anonymous inner classes 1) What is the output of the following java program? public class Outer { public static int temp1 = 1; private static int temp2 = 2; public int temp3 = 3; private int temp4 = 4; public static class Inner { private static int temp5 = 5; private static int getSum() { return (temp1 + temp2
3 min read
Inner reducing pattern printing
Given a number N, print the following pattern. Examples : Input : 4 Output : 4444444 4333334 4322234 4321234 4322234 4333334 4444444 Explanation: (1) Given value of n forms the outer-most rectangular box layer. (2) Value of n reduces by 1 and forms an inner rectangular box layer. (3) The step (2) is repeated until n reduces to 1. Input : 3 Output :
5 min read
Java.lang.Class class in Java | Set 1
Java provides a class with name Class in java.lang package. Instances of the class Class represent classes and interfaces in a running Java application. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects. It has no public constructor. Class objects are cons
15+ min read
Java.lang.Class class in Java | Set 2
Java.lang.Class class in Java | Set 1 More methods: 1. int getModifiers() : This method returns the Java language modifiers for this class or interface, encoded in an integer. The modifiers consist of the Java Virtual Machine's constants for public, protected, private, final, static, abstract and interface. These modifiers are already decoded in Mo
15+ min read
Difference Between java.sql.Time, java.sql.Timestamp and java.sql.Date in Java
Across the software projects, we are using java.sql.Time, java.sql.Timestamp and java.sql.Date in many instances. Whenever the java application interacts with the database, we should use these instead of java.util.Date. The reason is JDBC i.e. java database connectivity uses these to identify SQL Date and Timestamp. Here let us see the differences
7 min read
Java.util.TimeZone Class (Set-2) | Example On TimeZone Class
TimeZone class (the methods of this class was discussed in this article Java.util.TimeZone Class | Set 1) can be used in many cases like using TimeZone class we can get the time difference in term of hour and minute between two places.Problem : How we can get time difference of time in terms of hours and minutes between two places of Earth?Solution
5 min read
Implement Pair Class with Unit Class in Java using JavaTuples
To implement a Pair class with a Unit class in Java using JavaTuples, you can use the Pair class provided by the library and create a new Unit class that extends the Unit class provided by the library. Here is an example implementation: Here is an example Java code that uses the MyPair class with MyUnit and displays the output: Java Code import org
4 min read
Implement Triplet Class with Pair Class in Java using JavaTuples
Following are the ways to implement Triplet Class with Pair Class Using direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // create Pair Pair<Integer, String> pair = new Pair<Integer, String>( Integer.valueOf(1), "GeeksforGeeks"); // Print the Pair System.out.printl
2 min read
Implement Quintet Class with Quartet Class in Java using JavaTuples
Following are the ways to implement Quintet Class with Quartet Class Using direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // create Quartet Quartet<String, String, String, String> quartet = new Quartet<String, String, String, String>( "Quartet", "Triplet
4 min read
Implement Quartet Class with Triplet Class in Java using JavaTuples
Following are the ways to implement Quartet Class with Triplet Class Using direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // create Triplet Triplet<String, String, String> triplet = new Triplet<String, String, String>( "Triplet 1", "1", "GeeksforGe
3 min read
Implement Octet Class from Septet Class in Java using JavaTuples
Prerequisite: Octet Class, Septet Class Below are the methods to implement a Octet Class using Septet Class in Java: Using direct values // Java program to illustrate // implementing Octet Class // from Septet Class // using direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // Create Sep
6 min read
Implement Ennead Class from Octet Class in Java using JavaTuples
Prerequisite: Ennead Class, Octet Class Below are the methods to implement a Ennead Class using Octet Class in Java: Using direct values // Java program to illustrate // implementing Ennead Class // from Octet Class // using direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // Create Oct
7 min read
Implement Sextet Class from Quintet Class in Java using JavaTuples
Prerequisite: Sextet Class, Quintet Class Below are the methods to implement a Sextet Class using Quintet Class in Java: Using direct values // Java program to illustrate // implementing Sextet Class // from Quintet Class using // direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // crea
5 min read
Implement Septet Class from Sextet Class in Java using JavaTuples
Prerequisite: Septet Class, Sextet Class Below are the methods to implement a Septet Class using Sextet Class in Java: Using direct values // Java program to illustrate // implementing Septet Class // from Sextet Class // using direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // Create
6 min read
Implement Decade Class from Ennead Class in Java using JavaTuples
Prerequisite: Decade Class, Ennead Class Below are the methods to implement a Decade Class using Ennead Class in Java: Using direct values // Java program to illustrate // implementing Decade Class // from Ennead Class // using direct values import java.util.*; import org.javatuples.*; class GfG { public static void main(String[] args) { // Create
8 min read
Difference between Abstract Class and Concrete Class in Java
Abstract Class: An abstract class is a type of class in Java that is declared by the abstract keyword. An abstract class cannot be instantiated directly, i.e. the object of such class cannot be created directly using the new keyword. An abstract class can be instantiated either by a concrete subclass or by defining all the abstract method along wit
5 min read
Java I/O Operation - Wrapper Class vs Primitive Class Variables
It is better to use the Primitive Class variable for the I/O operation unless there is a necessity of using the Wrapper Class. In this article, we can discuss briefly both wrapper class and primitive data type. A primitive data type focuses on variable values, without any additional methods.The Default value of Primitive class variables are given b
3 min read
Using predefined class name as Class or Variable name in Java
In Java, you can use any valid identifier as a class or variable name. However, it is not recommended to use a predefined class name as a class or variable name in Java. The reason is that when you use a predefined class name as a class or variable name, you can potentially create confusion and make your code harder to read and understand. It may a
5 min read
Why BufferedReader class takes less time for I/O operation than Scanner class in java
In Java, both BufferReader and Scanner classes can be used for the reading inputs, but they differ in the performance due to their underlying implementations. The BufferReader class can be generally faster than the Scanner class because of the way it handles the input and parsing. This article will guide these difference, provide the detailed expla
3 min read
Java.io.ObjectInputStream Class in Java | Set 2
Java.io.ObjectInputStream Class in Java | Set 1 Note : Java codes mentioned in this article won't run on Online IDE as the file used in the code doesn't exists online. So, to verify the working of the codes, you can copy them to your System and can run it over there. More Methods of ObjectInputStream Class : defaultReadObject() : java.io.ObjectInpu
6 min read
Java.lang.StrictMath class in Java | Set 2
Java.lang.StrictMath Class in Java | Set 1More methods of java.lang.StrictMath class 13. exp() : java.lang.StrictMath.exp(double arg) method returns the Euler’s number raised to the power of double argument. Important cases: Result is NaN, if argument is NaN.Result is +ve infinity, if the argument is +ve infinity.Result is +ve zero, if argument is
6 min read
java.lang.instrument.ClassDefinition Class in Java
This class is used to bind together the supplied class and class file bytes in a single ClassDefinition object. These class provide methods to extract information about the type of class and class file bytes of an object. This class is a subclass of java.lang.Object class. Class declaration: public final class ClassDefinition extends ObjectConstruc
2 min read
java.net.URLConnection Class in Java
URLConnection Class in Java is an abstract class that represents a connection of a resource as specified by the corresponding URL. It is imported by the java.net package. The URLConnection class is utilized for serving two different yet related purposes, Firstly it provides control on interaction with a server(especially an HTTP server) than URL cl
5 min read
Java.util.GregorianCalendar Class in Java
Prerequisites : java.util.Locale, java.util.TimeZone, Calendar.get()GregorianCalendar is a concrete subclass(one which has implementation of all of its inherited members either from interface or abstract class) of a Calendar that implements the most widely used Gregorian Calendar with which we are familiar. java.util.GregorianCalendar vs java.util.
10 min read
Article Tags :
Practice Tags :
three90RightbarBannerImg