2

I was reading Kathy and Bert SCJP 1.6 and encountered the following code :

class Bar {
int barNum = 28;
}

class Foo {
  Bar myBar = new Bar();
  void changeIt(Bar myBar) {
    myBar.barNum = 99;
    System.out.println("myBar.barNum in changeIt is " + myBar.barNum);
    myBar = new Bar();
    myBar.barNum = 420;
    System.out.println("myBar.barNum in changeIt is now " + myBar.barNum);
 }
  public static void main (String [] args) {
    Foo f = new Foo();
    System.out.println("f.myBar.barNum is " + f.myBar.barNum);
    f.changeIt(f.myBar);
    System.out.println("f.myBar.barNum after changeIt is "
    + f.myBar.barNum);
 }
}

While it was under the topic of shadowing variables, I cannot understand how the non-static variable myBar can be referenced inside the main() method (static)?

Aman Grover
  • 1,621
  • 1
  • 21
  • 41
  • possible duplicate of [What is the reason behind "non-static method cannot be referenced from a static context"?](http://stackoverflow.com/questions/290884/what-is-the-reason-behind-non-static-method-cannot-be-referenced-from-a-static) – TheLostMind Sep 26 '14 at 14:33

2 Answers2

5

The trick is that the context of the myBar access isn't static.

By writing f.myBar instead of just simply myBar, you access it in the context of the instance stored in f (a local variable).

This is the basis of an often used pattern to launch applications.

public class Main {
   private final Foo param1;
   private final Bar param2;       


   private Main( Foo initParam1, Bar initParam2 ) {
      //initialise the fields 
   }

   private void run() {
      // execute the application
   }

   public static void main( String [] args ) {
      // parse the command line arguments
      Foo parsedParam1 = ...
      Bar parsedParam2 = ...
      Main main = new Main( parsedParam1, parsedParam2 );
      main.run();
   }
}
biziclop
  • 48,926
  • 12
  • 77
  • 104
3

static variable in Java belongs to the Class and its value remains same for all instances of that class. static variable is initialized when class is loaded into JVM.

On the other hand instance variable has different value for each instances. They get created when instance of an object is created either by using new operator or using reflection like Class.newInstance(). So in your case:

/* this is valid since compiler knows myBar
belongs to an instance of Foo called f */
Foo f = new Foo();
f.changeIt(f.myBar);  

/* This is invalid because compiler doesn't know which
myBar this is since it isn't connected to a class */
Foo f = new Foo();
f.changeIt(myBar); 

So if you try to access a non static variable without any instance compiler will give you an error because those variables are not yet created and thus don't exist.

nem035
  • 34,790
  • 6
  • 87
  • 99