Java Inner Class

The inner Java class defines the body of another class. The inner class can define as private, public, secure, or with standard access, while an outer class can only have public or standard access.

Therefore the Java nested classes have two types.

1. Static nested class

If the nested class is static then it is known as a static nested class. Static members of the outer class can only access Static nested classes. A static nested class is the same as any other top-level class and is nested for packaging purposes only.

You can create a static class object using the following statement.

OuterClass.StaticNestedClass nestedObject =
     new OuterClass.StaticNestedClass();

2. Java inner class

Any nested class that is not static is called an inner class in Java. The inner Java class is assigned to the class object, and all variables and methods of the outer class are accessible.
Since inner classes are assigned to the instance, we cannot contain static variables.
The Java inner class object is part of the outer class object. To instantiate the inner class, we must first instantiate the outer class.

The inner Java class can instantiate like this.

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

There are two kinds of Java inner classes.

1. Local inner class

When a class is defined in the body of a method, it is called a local inner class.

Since the local inner class is not associate with Object, we cannot use private, public, or secure access modifiers with it. The only allowable modifiers are abstract or final.

A local inner class can access all members of the enclosing class and local final variables in the scope it defines. It can also access a non-final local variable of the method in which define but does not change it. So if you try to print the value of the local variable which is not the last variable. But if you try to change the value from the local class of method. You will find sorting errors.

A local inner class can define as shown in the below program.

package com.HandyOpinion.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();

	}
}

Therefore we can also specify a local internal class within each block, such as a static block, if and else, etc. However, in this case, the scope of the class is 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

An unnamed local inner class is known as an anonymous inner class. and the Anonymous inner class is called an anonymous inner class. An anonymous class is explained and instantaneous in a single statement.

An anonymous internal class always extends to a class or implements an interface. Because anonymous classes have no names. Therefore, it is not possible to specify a constructor for an anonymous class.

Anonymous inner classes are only accessible where they are defined.
It is a little difficult to define how to create an anonymous inner class, we will see its use in real time in the test program below.

Here is a Java class showing how to define a Java inner class, a stable home class, a local inner class, and an anonymous inner class.

OuterClass.java

package com.HandyOpinion.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 code where you can see how to instantiate and use the inner class in java.

InnerClassTest.java

package com.HandyOpinion.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")));
    }

}

Output

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]

Note that when you configure the OuterClass, separate class files are created for the inner class, the local inner class, and the initial static class.

Following are the advantages of the inner Java class

  • When a class is only useful to one class, it makes sense to nest and joins them together and help with class packing.
  • Inner Java classes implement the encapsulation. Notice that the inner class can access the private members of the outer class and at the same time we can hide the inner class from the outside world.
  • By placing a small class in extendable classes, the code stays close to where it is used and allows for better readability and storage of the code.
Please share this post:
Posts created 51

Ask a Question

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

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

%d bloggers like this: