SCJP java Programmer certification Exam And Training. This site is entirely independent of Sun Microsystems Inc, The Sun Certified Java Programmers Exam (SCJP) is the internationally recognized java certification exam. This site offers free mock Exam preparation questions, practice tests, tutorials, certification faq and sample code. This site contains a very detailed tutorial organized by topic. At the end of the tutorial you can learn from your mistakes and apply your concepts on the free mock exams java certification practice tests.


Chapter 6 - Objects and Classes  (Part 4)

Part 1        Part 2        Part 3

// Example 1

public class InnerInnerTest {

  public static void main(String s[]) {

        new Outer().new Inner().new InnerInner().new InnerInnerInner().doSomething();

        new Outer().new InnerChild().doSomething();

        new Outer2().new Inner2().new InnerInner2().doSomething();

        new InnerChild2().doSomething();

  }

}

class Outer {

  String name = "Vel";

  class Inner {

        String name = "Sharmi";

        class InnerInner {

          class InnerInnerInner {

                public void doSomething() {

                  // No problem in accessing without full qualification,

                  // inner-most class variable shadows the outer-most class variable

                  System.out.println(name); // Prints "Sharmi"

                  System.out.println(Outer.this.name); // Prints "Vel", explicit reference to Outer

// error, variable is not inherited from the outer class, it can be just accessible

//               System.out.println(this.name);

//               System.out.println(InnerInner.this.name);

//               System.out.println(InnerInnerInner.this.name);

// error, super cannot be used to access outer class.

// super will always refer the parent, in this case Object

//               System.out.println(super.name); 

                  System.out.println(Inner.this.name); // Prints "Sharmi", Inner has declared 'name'

                }

          }

        }

  }

  /* This is an inner class extending an inner class in the same scope */

  class InnerChild extends Inner {

        public void doSomething() {

// compiler error, explicit qualifier needed

// 'name' is inherited from Inner, Outer's 'name' is also in scope

//       System.out.println(name);

          System.out.println(Outer.this.name); // prints "Vel", explicit reference to Outer

          System.out.println(super.name); // prints "Sharmi", Inner has declared 'name'

          System.out.println(this.name); // prints "Sharmi", name is inherited by InnerChild

        }

  }

}

class Outer2 {

  static String name = "Vel";

  static class Inner2 {

        static String name = "Sharmi";

        class InnerInner2 {

          public void doSomething() {

            System.out.println(name); // prints "Sharmi", inner-most hides outer-most

            System.out.println(Outer2.name); // prints "Vel", explicit reference to Outer2's static variable

//         System.out.println(this.name); // error, 'name' is not inherited

//         System.out.println(super.name); // error, super refers to Object

          }

        }

  }

}

/* This is a stand-alone class extending an inner class */

class InnerChild2 extends Outer2.Inner2 {

        public void doSomething() {

          System.out.println(name); // prints "Sharmi", Inner2's name is inherited

          System.out.println(Outer2.name); // prints "Vel", explicit reference to Outer2's static variable

          System.out.println(super.name); // prints "Sharmi", Inner2 has declared 'name'

          System.out.println(this.name); // prints "Sharmi", name is inherited by InnerChild2

        }

}

// Example 2

public class InnerTest2 {

  public static void main(String s[]) {

                new OuterClass().doSomething(10, 20);

// This is legal

//                OuterClass.InnerClass ic = new OuterClass().new InnerClass();

//                ic.doSomething();

// Compiler error, local inner classes cannot be accessed from outside

//                OuterClass.LocalInnerClass lic = new OuterClass().new LocalInnerClass();

//                lic.doSomething();                                               

                new OuterClass().doAnonymous();

  }

}

class OuterClass {

  final int a = 100;

  private String secret = "Nothing serious";

  public void doSomething(int arg, final int fa) {

                final int x = 100;

                int y = 200;

                System.out.println(this.getClass() + " - in doSomething");

                System.out.print("a = " + a + " secret = " + secret + " arg = " + arg + " fa = " + fa);

                System.out.println(" x = " + x + " y = " + y);

// Compiler error, forward reference of local inner class

//                new LocalInnerClass().doSomething();

                abstract class AncestorLocalInnerClass { } // inner class can be abstract

                final class LocalInnerClass extends AncestorLocalInnerClass { // can be final

                  public void doSomething() {

                    System.out.println(this.getClass() + " - in doSomething"); 

                    System.out.print("a = " + a );

                    System.out.print(" secret = " + secret);

//                    System.out.print(" arg = " + arg);  // Compiler error, accessing non-final argument

                    System.out.print(" fa = " + fa);

                    System.out.println(" x = " + x);

//                    System.out.println(" y = " + y); // Compiler error, accessing non-final variable

                  }

                }

                new InnerClass().doSomething(); // forward reference fine for member inner class

                new LocalInnerClass().doSomething();

  }

  abstract class AncestorInnerClass { }

  interface InnerInterface { final int someConstant = 999;} // inner interface

  class InnerClass extends AncestorInnerClass implements InnerInterface {

    public void doSomething() {

      System.out.println(this.getClass() + " - in doSomething"); 

      System.out.println("a = " + a + " secret = " + secret + " someConstant = " + someConstant);

    }

  }

  public void doAnonymous() {

                // Anonymous class implementing the inner interface

                System.out.println((new InnerInterface() { }).someConstant);

                // Anonymous class extending the inner class

                ( new InnerClass() {

public void doSomething() {

  secret = "secret is changed";

  super.doSomething();

}

} ).doSomething();

  }

}

Entity

Declaration Context

Accessibility Modifiers

Outer instance

Direct Access to enclosing context

Defines static or non-static members

Package level class

As package member

Public or default

No

N/A

Both static and non-static

Top level nested class (static)

As static class member

All

No

Static members in enclosing context

Both static and non-static

Non static inner class

As non-static class member

All

Yes

All members in enclosing context

Only non-static

Local class (non-static)

In block with non-static context

None

Yes

All members in enclosing context + local final variables

Only non-static

Local class (static)

In block with static context

None

No

Static members in enclosing context + local final variables

Only non-static

Anonymous class (non-static)

In block with non-static context

None

Yes

All members in enclosing context + local final variables

Only non-static

Anonymous class (static)

In block with static context

None

No

Static members in enclosing context + local final variables

Only non-static

Package level interface

As package member

Public or default

No

N/A

Static variables and non-static method prototypes

Top level nested interface (static)

As static class member

All

No

Static members in enclosing context

Static variables and non-static method prototypes

Chapter 6 - Objects and Classes  (Part 4)

Part 1        Part 2        Part 3