Email address:
Password:
SCJP/OCPJP 1.6 certification
Practice Exams and Training
SCJP Online Training » Discussions

Is the runNow() method in class A not visible to class B because B can access only static members of A ?

Moreover if the runNow() method is not accessible to the classes B and C, should'nt it print "Low Out". Please tell me where am I going wrong.

When there is an inner class, which extends its own outer class, is trying to access its outer class members, there are two different channels the inner class can do that:


Channel 1: Through the members inherited from the outer class to the inner class due to inheritance.

Channel 2: Through direct access to the outer class / outer class object (in case of a non-static inner class).


.. in the above order.


You can create a little program to see which channel it uses. Let's consider this one for example:


class A {
	
   public int x = 4;
    
   class B extends A {
        
      public void increase(){
         x++;
      }
        
      void printInnerX() {
         System.out.println(x);
      }
        
   }
    
   public void printOuterX() {
      System.out.println(x);
   }
    
   public static void main(String args[]) {
      new A().main();
   }
    
   public void main() {
      A a = new A();
      A.B b = a.new B();
    	
      b.increase();
    	
      a.printOuterX();
      b.printInnerX();
   }
    
}


This should give you the output of "4, 5".


Let's see why: the important part is at line-29, which calls the increase() method in the inner class. In line-8, you are trying to increase x. In order to increase x, the JVM has to see how it can access 'x'. So, it has channel-1 and channel-2. It first tries with ch-1, which has the idea of accessing the variable through inheritance. Since x is a public variable here, it sees it can access it through inheritance, and therefore, it uses ch-1, and increases x in the space of A inherited to B.


This leaves the original A object 'a' unaffected. So, as line-31 tries to access 'x', it therefore prints 4 - the unaffected value in that object.


When it comes to the line-32, it makes line-12 access 'x' again. Same is before, it sees it can use ch-1, so it uses it, and accesses the 'x' in the space of A inherited to B, which is now 5. So it prints 5.



I know it seems all okay so far, but here's the most important twist: go to line-3 and replace public with private, so 'x' becomes a private variable.

Guess how this would change the outcome! The twist is the program will now print "5, 5" (instead of "5, 4" which it printed when 'x' was public). This is an extreme case, where a simple change to a visibility modifier would give you the completely opposite outcome!


What happens in this case is ch-1 becomes unavailable due to the variable x being private. This is because when x is private, it does not get inherited to the sub classes of that class. Now, since ch-1 is unavailable, the JVM has to look for ch-2, which is the direct access to the outer class object object (which is same the object what a refers in this case). Since that is the only 'x' it can increase and print, it will print "5, 5" this time.


Does this channel conflict give you a little clue for you to answer your own question? Which channel do you think we use in our original program given in the question?

ExamLab © 2008 - 2024