Tutorial

Java Inner Class

Published on August 3, 2022
Default avatar

By Pankaj

Java Inner Class

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Java inner class is defined inside the body of another class. Java inner class can be declared private, public, protected, or with default access whereas an outer class can have only public or default access. Java Nested classes are divided into two types.

  1. static nested class

    If the nested class is static, then it’s called a static nested class. Static nested classes can access only static members of the outer class. A static nested class is the same as any other top-level class and is nested for only packaging convenience. A static class object can be created with the following statement.

    OuterClass.StaticNestedClass nestedObject =
         new OuterClass.StaticNestedClass();
    
  2. java inner class

    java inner class Any non-static nested class is known as inner class in java. Java inner class is associated with the object of the class and they can access all the variables and methods of the outer class. Since inner classes are associated with the instance, we can’t have any static variables in them. The object of java inner class are part of the outer class object and to create an instance of the inner class, we first need to create an instance of outer class. Java inner class can be instantiated like this;

    OuterClass outerObject = new OuterClass();
    OuterClass.InnerClass innerObject = outerObject.new InnerClass();
    

There are two special kinds of Java inner classes.

  1. local inner class

    If a class is defined in a method body, it’s known as local inner class. Since the local inner class is not associated with Object, we can’t use private, public or protected access modifiers with it. The only allowed modifiers are abstract or final. A local inner class can access all the members of the enclosing class and local final variables in the scope it’s defined. Additionally, it can also access a non-final local variable of the method in which it is defined, but it cannot modify them. So if you try to print non-final local variable’s value it will be allowed but if you try to change its value from inside method local inner class, you will get compile time Error. Local inner class can be defined as:

    package com.journaldev.innerclasses;
    
    public class MainClass {
    
    	private String s_main_class;
    
    	public void print() {
    		String s_print_method = "";
    		// local inner class inside the method
    		class Logger {
    			// able to access enclosing class variables
    			String name = s_main_class; 
    			// able to access non-final method variables
    			String name1 = s_print_method; 
    
    			public void foo() {
    				String name1 = s_print_method;
    				// Below code will throw compile time error:
    				// Local variable s_print_method defined in an enclosing scope must be final or effectively final 
    				// s_print_method= ":";
    			}
    		}
    		// instantiate local inner class in the method to use
    		Logger logger = new Logger();
    
    	}
    }
    

    We can define a local inner class inside any block too, such as static block, if-else block etc. However, in this case, the scope of the class will be very limited.

    public class MainClass {
    
    	static {
    		class Foo {
    			
    		}
    		Foo f = new Foo();
    	}
    	
    	public void bar() {
    		if(1 < 2) {
    			class Test {
    				
    			}
    			Test t1 = new Test();
    		}
    		// Below will throw error because of the scope of the class
    		//Test t = new Test();
    		//Foo f = new Foo();
    	}
    }
    
  2. anonymous inner class

    A local inner class without name is known as anonymous inner class. An anonymous class is defined and instantiated in a single statement. Anonymous inner class always extend a class or implement an interface. Since an anonymous class has no name, it is not possible to define a constructor for an anonymous class. Anonymous inner classes are accessible only at the point where it is defined. It’s a bit hard to define how to create an anonymous inner class, we will see it’s real-time usage in the test program below.

Here is a java class showing how to define java inner class, static nested class, local inner class, and an anonymous inner class. OuterClass.java

package com.journaldev.nested;

import java.io.File;
import java.io.FilenameFilter;

public class OuterClass {
    
    private static String name = "OuterClass";
    private int i;
    protected int j;
    int k;
    public int l;

    //OuterClass constructor
    public OuterClass(int i, int j, int k, int l) {
        this.i = i;
        this.j = j;
        this.k = k;
        this.l = l;
    }

    public int getI() {
        return this.i;
    }

    //static nested class, can access OuterClass static variables/methods
    static class StaticNestedClass {
        private int a;
        protected int b;
        int c;
        public int d;

        public int getA() {
            return this.a;
        }

        public String getName() {
            return name;
        }
    }

    //inner class, non-static and can access all the variables/methods of the outer class
    class InnerClass {
        private int w;
        protected int x;
        int y;
        public int z;

        public int getW() {
            return this.w;
        }

        public void setValues() {
            this.w = i;
            this.x = j;
            this.y = k;
            this.z = l;
        }

        @Override
        public String toString() {
            return "w=" + w + ":x=" + x + ":y=" + y + ":z=" + z;
        }

        public String getName() {
            return name;
        }
    }

    //local inner class
    public void print(String initial) {
        //local inner class inside the method
        class Logger {
            String name;

            public Logger(String name) {
                this.name = name;
            }

            public void log(String str) {
                System.out.println(this.name + ": " + str);
            }
        }

        Logger logger = new Logger(initial);
        logger.log(name);
        logger.log("" + this.i);
        logger.log("" + this.j);
        logger.log("" + this.k);
        logger.log("" + this.l);
    }

    //anonymous inner class
    public String[] getFilesInDir(String dir, final String ext) {
        File file = new File(dir);
        //anonymous inner class implementing FilenameFilter interface
        String[] filesList = file.list(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String name) {
                return name.endsWith(ext);
            }

        });
        return filesList;
    }
}

Here is the test program showing how to instantiate and use the inner class in java. InnerClassTest.java

package com.journaldev.nested;

import java.util.Arrays;
//nested classes can be used in import for easy instantiation
import com.journaldev.nested.OuterClass.InnerClass;
import com.journaldev.nested.OuterClass.StaticNestedClass;

public class InnerClassTest {

    public static void main(String[] args) {
        OuterClass outer = new OuterClass(1,2,3,4);
        
        //static nested classes example
        StaticNestedClass staticNestedClass = new StaticNestedClass();
        StaticNestedClass staticNestedClass1 = new StaticNestedClass();
        
        System.out.println(staticNestedClass.getName());
        staticNestedClass.d=10;
        System.out.println(staticNestedClass.d);
        System.out.println(staticNestedClass1.d);
        
        //inner class example
        InnerClass innerClass = outer.new InnerClass();
        System.out.println(innerClass.getName());
        System.out.println(innerClass);
        innerClass.setValues();
        System.out.println(innerClass);
        
        //calling method using local inner class
        outer.print("Outer");
        
        //calling method using anonymous inner class
        System.out.println(Arrays.toString(outer.getFilesInDir("src/com/journaldev/nested", ".java")));
        
        System.out.println(Arrays.toString(outer.getFilesInDir("bin/com/journaldev/nested", ".class")));
    }

}

Here is the output of the above java inner class example program.

OuterClass
10
0
OuterClass
w=0:x=0:y=0:z=0
w=1:x=2:y=3:z=4
Outer: OuterClass
Outer: 1
Outer: 2
Outer: 3
Outer: 4
[NestedClassTest.java, OuterClass.java]
[NestedClassTest.class, OuterClass$1.class, OuterClass$1Logger.class, OuterClass$InnerClass.class, OuterClass$StaticNestedClass.class, OuterClass.class]

Notice that when OuterClass is compiled, separate class files are created for the inner class, local inner class, and static nested class.

Benefits of Java Inner Class

  1. If a class is useful to only one class, it makes sense to keep it nested and together. It helps in the packaging of the classes.
  2. Java inner classes implements encapsulation. Note that inner classes can access outer class private members and at the same time we can hide inner class from outer world.
  3. Keeping the small class within top-level classes places the code closer to where it is used and makes the code more readable and maintainable.

That’s all for java inner class.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Pankaj

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
January 6, 2021

I am running my own website Learned alot. from you. great contents. I am visiting your blog. It’s awesome.

- AlixaProDev

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    September 21, 2020

    Dear pankajbhai, I must say thank you for wonderful work. You are skilled gifted by God. Thank you so much for this information. Thank you…

    - Parth Trivedi

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      May 30, 2020

      Great content! Thanks a lot!

      - Vladimir

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        December 19, 2019

        It’s more helpful for interview purpose thank you.

        - satheesh

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          April 9, 2019

          Hi Pankaj, The inline code is not available for any of your posts. Can you please suggest what needs to be done? Without the code referenced in your text, there is very less meaning to the post. Thank you!!

          - Priyanka

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            November 18, 2018

            Thnxx it’s very nyc Mere liye kafi helping resources thnxx

            - roma jha

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              June 22, 2018

              The statement about Method Local Inner Classes needs changes. It says “A local inner class can access all the members of the enclosing class and local final variables in the scope it’s defined.”. The correct statement should be “A local inner class can access all the members of the enclosing class and local final variables in the scope it’s defined. Additionally it can also access non final local variable of method in which it is defined, but it cannot modify them. So if you try to print non final local variable’s value it will be allowed but if you try to change its value from inside method local inner class, you will get compile time Error”

              - Amol Bhonsle

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                February 22, 2018

                for local inner class we can access local non-final variable in the scope it’s defined.(java version 8 and above)

                - Ganesh

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  November 18, 2016

                  What are the benefits of annonymous inner class? Explain with example.

                  - Sundara Baskaran

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    July 17, 2015

                    Since inner classes are associated with instance, we can’t have any static variables in them… true but If we use ‘static final int mytest=0 ;’ it is allowed!

                    - Deepak

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Get our biweekly newsletter

                      Sign up for Infrastructure as a Newsletter.

                      Hollie's Hub for Good

                      Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

                      Become a contributor

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      Welcome to the developer cloud

                      DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Learn more
                      DigitalOcean Cloud Control Panel