Java inner class or non-static nested class is the most prevalent type of nested class among those Java provides. A Java inner class has access to all of the methods and variables (even they are private
) of the enclosing class as if these methods and variables have been declared within the inner class. But the opposite is not true; enclosing class cannot access directly the members of inner class.
Let's see how is a Java inner class defined and compiled?
/* OuterClass.java */ public class OuterClass { class InnerClass { //non-static inner class } } [root@host ~]#javac OuterClass.java [root@host ~]#ls ... OuterClass$InnerClass.class OuterClass.class ...
After compiling OuterClass.java
you see there are two class files are generated. It is because Java generates separate class file for every class even if it is an inner class. Here InnerClass
is an inner class yet it is a separate class so a separate class file is generated. But, remember that you cannot access OuterClass$InnerClass.class
in a usual way as you access top level classes. The only way you can access the Java inner class is through a live instance of the enclosing outer class.
As it has been mentioned, a Java inner class can be accessed only through a live instance of outer class. So, to create an instance of Java inner class (InnerClass
) you must have an instance of enclosing outer class (OuterClass
).
Mostly, Java inner classes are defined to assist outer classes in some way, so it is the outer class usually creates instance(s) of inner class. Let's modify the OuterClass
to create an instance of InnerClass
.
/* OuterClass.java */ public class OuterClass { private int outerMem = 10; public void createInnerClassInst() { InnerClass ic = new InnerClass(); ic.getOuterMem(); } class InnerClass { public void getOuterMem() { System.out.println("OuterMem accessed from InnerClass: " + outerMem); } } //InnerClass closed } //OuterClass closed
See the above code where OuterClass
code treats InnerClass
as if InnerClass
is any other accessible class. Within from the method createInnerClassInst()
, class OuterClass
creates an object using the class name new InnerClass()
, and then invokes the method getOuterMem()
on the reference variable as ic.getOuterMem()
.
The below piece of code demonstrates object creation of OuterClass
and then access its own member outerMem
through an object of InnerClass
.
/* InnerClassDemo.java */ public class InnerClassDemo { public static void main(String[] args) { OuterClass oc = new OuterClass(); oc.createInnerClassInst(); } } OUTPUT ------ OuterMem accessed from InnerClass: 10
Above piece of code works because the OuterClass
instance oc
calls createInnerClassInst()
method that instantiates an object of InnerClass
. So there should be an instance of outer class that further creates an instance of Java inner class (InnerClass
).
You may now be thinking that is there any way to create an object of Java inner class InnerClass
from somewhere outside the outer class OuterClass
? Is it possible? Of course it is, but in that case the visibility of the Java inner class should either be default or public
. In our example code the visibility of InnerClass
is default, thus it is visible within the same package.
So, if we want to create an instance of Java inner class InnerClass
somewhere outside the outer class OuterClass
instance code then we must have an instance of OuterClass
. As you already know that without an object of the outer class you cannot create an object of the Java inner class from any other code in any other class. A Java inner class object is always bounded to an outer class object. The compiler takes care of it and you see the end results only (the ability to access members of outer class). Have a look at following piece of code and you will understand.
public class InnerClassDemo { public static void main(String[] args) { OuterClass oc = new OuterClass(); oc.createInnerClassInst(); // Creating InnerClass's instance by // an instance of OuterClass 'oc' OuterClass.InnerClass icc = oc.new InnerClass(); icc.getOuterMem(); //One liner way to create an inner class object OuterClass.InnerClass iccc = new OuterClass().new InnerClass(); iccc.getOuterMem(); } } OUTPUT ------ OuterMem accessed from InnerClass: 10 OuterMem accessed from InnerClass: 10 OuterMem accessed from InnerClass: 10
Read the above piece of code carefully and see the difference between inner class object creation code that is within outer class, and inner class object creation code that is outside the outer class:
InnerClass ic = new InnerClass();
new OuterClass().new InnerClass();
or oc.new InnerClass();
oc
is already created instance of OuterClass
.
In order to understand accessing outer class instance within from Java inner class we have to first look at the functionality of this
operator. As we know an object refers to itself by using this
reference. But, this
reference has some limitations. First, this
can be used within from non-static instance code only, not within from static
methods because static
methods can be executed even without creating an object. Second, this
refers to the current object. And third, this
reference is the way an object can pass a reference to itself.
Within a Java inner class this
reference refers to the instance of the inner class. But, if you sometimes need an explicit reference to the outer class or enclosing class instance that the inner class is tied to then use OuterClass.this
. Following is an example:
/* InnerOuterThisDemo.java */ public class InnerOuterThisDemo { public static void main(String[] args) { Outer.Inner i = new Outer().new Inner(); i.AccessOuterThis(); } } class Outer { int onum = 10; class Inner { public void AccessOuterThis () { System.out.println("Outer member onum: " + onum); System.out.println("Inner class reference is: " + this); System.out.println("Outer class reference is: " + Outer.this); } } } OUTPUT ------ Outer member onum: 10 Inner class reference is: Outer$Inner@360be0 Outer class reference is: Outer@45a877
The output from above code gives you the class name followed by @ symbol, followed by the unsigned hexadecimal representation of the object's hash code.
In this tutorial we talked of Java inner class. A Java inner class is a member of the outer class just like other variables and methods, so the same modifiers applied to other variables can be applied to Java inner class too. For example a Java inner class can be declared final
, abstract
, public
, private
, protected
, and strictfp
but static
. Because static
turns it into a Java static nested class not a Java inner class. Hope you have enjoyed reading this tutorial. Please do write us if you have any suggestion/comment or come across any error on this page. Thanks for reading!
Share this page on WhatsApp