In Part 1, I’ve covered the basics, in part 2, anonymous inner classes. Is there anything left about inner classes? Yes, there is. I warned you that inner classes are a beast.
In this part, I’ll cover nested classes.
When you create an inner class, there is a connection between the enclosed class and the inner class. Because of that, the inner class can access and manipulate the enclosed class.
Take that connection away and you have a nested class. A nested class is a static inner class. With a nested class, 1) you don’t need an outer class to create the instance and 2) you can’t access non-static outer-class object from the nested instance. Below is an example.
public class StaticInner { String s = "test"; public static class Inner { private int counter = 1; public int increment() { return counter++; } public void printS() { // StaticInner.this.s; // ERROR: No enclosing instance of the type StaticInner is // accessible in scope } } public static class Inner2 { private static int counter = 1; public static int increment() { return counter++; } } public static class Inner3 { public static class Inner3Inner { public void sayHi() { System.out.println("Hi"); } } } public static void main(String[] args) { System.out.println("Inner"); Inner inner = new Inner(); System.out.println(inner.increment()); // "1" System.out.println(inner.increment()); "2" Inner inner2 = new Inner(); System.out.println(inner2.increment()); // "1" // Inner2 has a static method System.out.println("Inner2"); System.out.println(Inner2.increment()); // "1" System.out.println(Inner2.increment()); // "2" // Inner3 has an inner class System.out.println("Inner3Inner"); Inner3Inner subInner = new Inner3Inner(); subInner.sayHi(); // "Hi" } }
In the main method, you can see that you can just instantiate Inner with new Inner(). Also in Inner, printS method tries to access StaticInner variable but it’s not allowed to. There is no connection between the two classes.
Initially, I thought a “static class” can have only one instance. That’s not true. Inner can have multiple instances, inner2 is a seperate instance and has its own object.
Inner2 is an example of a static instance. You can refer to in directly by Inner2.increment().
Inner2 shows that static inners can have more than one layer, Inner3Inner is defined inside Inner3.
Yes, you read that correctly. You can have an inner class within an interface! I did not know this was possible. Not that I would want to use it, but still… Take a look at the following example.
// Thinking in Java example public interface ClassInInterface { void howdy(); class Test implements ClassInInterface { public void howdy() { System.out.println("Howdy!"); } } } // Usage ClassInInterface test = new Test(); test.howdy(); /* Output: Howdy!*/// :~
It’s completely valid! Why would you want to do it that way? One valid reason is that if you wanted to have a common implementation of the interface. The downside is that the interface is “heavier” to carry around, but that’s probably very minor.
Back to the basic inner classes. Does a 2nd or 3rd level inner class have access to the layers above? Yes, it does, it has access to all layers. Thinking in Java has a great example, see below.
// Nested classes can access all members of all // levels of the classes they are nested within. class MNA { private void f() { } class A { private void g() { } public class B { void h() { g(); f(); } } } } public class MultiNestingAccess { public static void main(String[] args) { MNA mna = new MNA(); MNA.A mnaa = mna.new A(); MNA.A.B mnaab = mnaa.new B(); mnaab.h(); } } // /:~
I don’t like long tutorials nor long chapters. That’s why I’m breaking these into parts. When will it end? I have done 3 parts already and I’m not done! In Part 4, I’ll try to cover another advanced topic, Multiple Inheritance. Bruce Eckel has an interesting example.
Reference
Thinking in Java (4th), Bruce Eckel
Java Inner Classes – Part 1 – Intro
Java Inner Classes – Part 2 – Anonymous