class OuterClass { private String outerClassPrivateInstanceVar = "outerClassPrivateInstanceVar"; public static String outerClassPublicStaticVar = "outerClassPublicStaticVar"; public String outerClassPublicInstanceVar = "outerClassPublicInstanceVar"; void outerClassInstanceMethod() { System.out.println("Inside outerClassInstanceMethod."); } static void outerClassStaticMethod() { System.out.println("Inside outerClassStaticMethod."); } // NON-STATIC Inner class class InnerClass { // Non-static innerClass cannot have static members. Following will not work. // static String InnerClassStaticVar = "InnerClassStaticVar"; public void innerClassMethod() { System.out.println("Inside innerClassMethod."); } public void innerClassAccessOuterClassVars() { System.out.println(outerClassPrivateInstanceVar); System.out.println(outerClassPublicInstanceVar); System.out.println(outerClassPublicStaticVar); } } // STATIC Inner class static class InnerClassStatic { // Following is allowed in Static InnerClass but not in non-static inner class. static String StaticInnerClassStaticVar = "StaticInnerClassStaticVar"; String InnerClassStaticInstanceVar = "InnerClassStaticInstanceVar"; public void innerClassStaticMethod() { System.out.println("Inside InnerClassStatic."); } public void innerClassStaticAccessOuterClassVars() { // Following will not work. Beacuse InnerClassStatic is like static member inside OuterClass // and static members/methods can never access instance members. //System.out.println(outerClassPrivateInstanceVar); //System.out.println(outerClassPublicInstanceVar); System.out.println(outerClassPublicStaticVar); } } // Local Inner Class inside Instance method. void outerClassInstanceMethodForLocalClass() { // Local Inner Classes cannot be private, protected, public and static. Because inside method // these keywords have no sense. We don't use these words inside methods. class LocalClassInInstanceMethod { // Static members are not allowed in Local Inner classes defined inside instance method. // Following will not work. //static String LocalClassInInstanceMethodStaticVar = "LocalClassInInstanceMethodStaticVar"; void localClassInInstanceMethod_instanceMethod() { System.out.println("Inside localClassInInstanceMethod_instanceMethod."); } } LocalClassInInstanceMethod localClassInInstanceMethodObj = new LocalClassInInstanceMethod(); localClassInInstanceMethodObj.localClassInInstanceMethod_instanceMethod(); } // Local Inner Class inside Static method. static void outerClassStaticMethodForLocalClass() { // Local Inner Classes cannot be private, protected, public and static. Because inside method // these keywords have no sense. We don't use these words inside methods. class LocalClassinStaticMethod { // Static members are not allowed in Local Inner classes defined inside static method. // Following will not work. //static String LocalClassinStaticMethodStaticVar = "LocalClassinStaticMethodStaticVar"; void LocalClassinStaticMethod_instanceMethod() { System.out.println("Inside LocalClassinStaticMethod_instanceMethod."); } } LocalClassinStaticMethod locallassinStaticMethodObj = new LocalClassinStaticMethod(); locallassinStaticMethodObj.LocalClassinStaticMethod_instanceMethod(); } // Anonymous Inner classes interface InnerInterface { void InnerInterfaceMethod(); } // Anonymous inner class object defined at class member level. InnerInterface anonymousClassObj = new InnerInterface() { public void InnerInterfaceMethod() { System.out.println("Inside InnerInterfaceMethod."); } }; void callAnonymousObjectMethod() { anonymousClassObj.InnerInterfaceMethod(); } // Anonymous inner class inside instance method. //void anonymousInnerClassInsideMethod() { OuterClass anonymousInnerClassInsideMethod() { OuterClass anon = new OuterClass() { void outerClassInstanceMethod() { System.out.println("Inside anonymousInnerClassInsideMethod."); } }; //anon.outerClassInstanceMethod(); return anon; } } public class InnerClassesTest { public static void main(String[] args) { OuterClass outerClassObj = new OuterClass(); // Call to instance method using instance variable. outerClassObj.outerClassInstanceMethod(); // Call to static method using instance variable. In Ruby there is something called self instead of static. And // self.outerClassStaticMethod in Ruby is actually a singleton method defined on a "class object (OuterClass)" and in Ruby class // itself is an object. And singleton methods can be called by only object on which it is defined, in this case OuterClass object. // Hence in Ruby object created by a class cannot access class method. Following is invalid in Ruby. outerClassObj.outerClassStaticMethod(); // NON-STATIC INNER CLASSES // Creating InnerClass object. System.out.println("====NON-STATIC INNER CLASSES===="); OuterClass.InnerClass innerClassObj = new OuterClass().new InnerClass(); innerClassObj.innerClassMethod(); // Following will not work. outerClassPublicInstanceVar is not defined in InnerClass. //System.out.println(innerClassObj.outerClassPublicInstanceVar); innerClassObj.innerClassAccessOuterClassVars(); // STATIC INNER CLASSES. // Creating Static Innerclass object. You will be using Class not object. System.out.println("====STATIC INNER CLASSES===="); OuterClass.InnerClassStatic innerClassStaticObj = new OuterClass.InnerClassStatic(); // You cannot use OuterClass object to use StaticInnerClass object. This is in contrast with creating InnerClass(non-static) object. // Also normally an object can access static class fields. But Following will not work. //OuterClass.InnerClassStatic innerClassStaticObj2 = outerClassObj.InnerClassStatic(); // Access static inner class' static member using static inner class' object. System.out.println(innerClassStaticObj.StaticInnerClassStaticVar); // Access static inner class' static member using Classes directly. System.out.println(OuterClass.InnerClassStatic.StaticInnerClassStaticVar); // Access static inner class' instance member using static inner class' object. System.out.println(innerClassStaticObj.InnerClassStaticInstanceVar); // LOCAL INNER CLASSES System.out.println("====LOCAL INNER CLASSES===="); outerClassObj.outerClassInstanceMethodForLocalClass(); outerClassObj.outerClassStaticMethodForLocalClass(); OuterClass.outerClassStaticMethodForLocalClass(); // ANONYMOUS INNER CLASSES System.out.println("====ANONYMOUS INNER CLASSES===="); outerClassObj.callAnonymousObjectMethod(); // Following works because, interface InnerInterface is visible in this class as well due to default access. // If inner interface in made private then following will not work. Only inner interfaces can be made private. outerClassObj.anonymousClassObj.InnerInterfaceMethod(); OuterClass anonymousObj = new OuterClass() { void outerClassInstanceMethod() { System.out.println("inside anonymousObjOfOuterClassSubClass Method."); } void anotherMethod() { System.out.println("Inside anotherMethod."); } }; anonymousObj.outerClassInstanceMethod(); // Following will not work. Because anonymousObj is refering to actually subclass of OuterClass (in memory). But it is declared as OuterClass. // That means, anonymousObj is actually a "Subclass of OuterClass" but its type is declared as OuterClass. Hence polymorphism will come in. // anonymousObj being declared as superclass variable will only be able to execute methods defined in super class not in sub class. Hence // following will not work. //anonymousObj.anotherMethod(); //Following works provided relevant lines are un-commented inside anonymousInnerClassInsideMethod instance method. //outerClassObj.anonymousInnerClassInsideMethod(); OuterClass out = outerClassObj.anonymousInnerClassInsideMethod(); out.outerClassInstanceMethod(); } }Compile and Output:
$ java -version java version "1.8.0_66" Java(TM) SE Runtime Environment (build 1.8.0_66-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode) $ $ javac InnerClassesTest.java $ java InnerClassesTest Inside outerClassInstanceMethod. Inside outerClassStaticMethod. ====NON-STATIC INNER CLASSES==== Inside innerClassMethod. outerClassPrivateInstanceVar outerClassPublicInstanceVar outerClassPublicStaticVar ====STATIC INNER CLASSES==== StaticInnerClassStaticVar StaticInnerClassStaticVar InnerClassStaticInstanceVar ====LOCAL INNER CLASSES==== Inside localClassInInstanceMethod_instanceMethod. Inside LocalClassinStaticMethod_instanceMethod. Inside LocalClassinStaticMethod_instanceMethod. ====ANONYMOUS INNER CLASSES==== Inside InnerInterfaceMethod. Inside InnerInterfaceMethod. inside anonymousObjOfOuterClassSubClass Method. Inside anonymousInnerClassInsideMethod.