Question

I am having problems understanding the way non-static variables are handled. I chose to work with an array so that it is easy to retrieve its memory address.

Consider the following code:

public class tryClass
{
    int[] v = {0}; // vector v is non-static (and NOT local to any method)
    tryClass obj;
    public void met ()
    {
        obj = new tryClass();
        obj.v[0] = 30;
        v[0]=3;
    }
    public static void main (String[] args)
    {
        tryClass obj = new tryClass(); // is this the SAME object as in met() ?
        int[] v = new int[1];
        obj.v[0] = 40;
        obj.met();
    }
}

In order to know at each step how vector v is handled I filled the code with some println instructions and my ouput is as follows:

In main(), BEFORE running met()
    obj.v[0] = 40
    obj.v    = [I@78456a0c

INSIDE method met()
    obj.v[0] = 30
    v[0]     = 3
    obj.v    = [I@15357784
    v        = [I@78456a0c

In main(), AFTER running met()
    obj.v[0] = 3
    obj.v    = [I@78456a0c

I am very puzzled by many things, the first of which is why the reference of obj.v when called in static method main() is the same as that of v inside non-static method met(). Besides, what exactly is v when called with no object (in a non-static context, of course)?

I am new to Java and I really have an infinity of questions, I hope an answer can solve them altogether... Thanks in advance for your help.

For the sake of completeness, the full code is

public class tryClass
{
    int[] v = {0};
    tryClass obj;
    public void met ()
    {
        obj = new tryClass();
        obj.v[0] = 30;
        v[0]=3;
        System.out.println("\nINSIDE method met()");
        System.out.println("\tobj.v[0] = "+obj.v[0]);
        System.out.println("\tv[0]     = "+v[0]);
        System.out.println("\tobj.v    = "+obj.v);
        System.out.println("\tv        = "+v);
    }
    public static void main (String[] args)
    {
        tryClass obj = new tryClass();
        int[] v = new int[1];
        obj.v[0] = 40;
        System.out.println("In main(), BEFORE running met()");
        System.out.println("\tobj.v[0] = "+obj.v[0]);
        System.out.println("\tobj.v    = "+obj.v);
        obj.met();
        System.out.println("\nIn main(), AFTER running met()");
        System.out.println("\tobj.v[0] = "+obj.v[0]);
        System.out.println("\tobj.v    = "+obj.v);
    }
}
Was it helpful?

Solution

Why is the reference of obj.v, when called in static method main() the same as that of v inside non-static method met()?

Answer: Because you didn't reassign it to a different object in memory. It's still pointing to the same "array" object in memory, even though you altered the contents of the array internally.

Looking at your code, with my comments:

public class tryClass
{
    // here, non-static variable v will be instantiated
    // as an array with a length of one, holding the value 0 in it's one slot;
    // it will be instantiated when an instance of tryClass is created.
    int[] v = {0};

    // here, this tryClass has another tryClass named "obj" in it as one of its fields.
    tryClass obj;

    public void met ()
    {
        // here, the tryClass's tryClass obj is instantiated
        // and this second tryClass's "v" is instantiated
        // and then it's one slot is set to 30.
        obj = new tryClass();
        obj.v[0] = 30;

        // now, the first tryClass's "v" is set to 3.
        v[0]=3;
    }

    public static void main (String[] args)
    {
        // creating a new tryClass.  This is NOT the same object as in met.
        // But it CONTAINS the same object in met.
        // You could call it by going obj.obj.
        tryClass obj = new tryClass(); // is this the SAME object as in met() ?  Answer: No.

        // this does nothing, it just creates another int[] v
        // that exists only inside the main() method.  It is not
        // the same as obj.v!
        int[] v = new int[1];

        // changing the contents of obj.v, but not reassigning obj.v itself.
        obj.v[0] = 40;

        // calling met, which will change obj.v's contents again, but not reassign it.
        obj.met();
    }
}

Arrays are mutable, meaning that even though it remains the same object in memory, it's contents can be altered.

OTHER TIPS

When you execute the static main method, the first thing you do is to create an instance of tryClass, and you print the value of one element of the array called v, which is an attribute of that instance. (obj.v[0]). Then you invoke the method met of that instance, so non static references in the body of that method refer to the attributes of that instance ( the one you created on main method).

You should also print out the obj reference's value, and when not in a static context, the value of this too. That would reveal, that you are printing the values of the v references for different instances of the tryClass class...

public class tryClass
{
    int[] v = {0};
    tryClass obj;
    public void met ()
    {
        obj = new tryClass();
        obj.v[0] = 30;
        v[0]=3;
        System.out.println("\nINSIDE method met()");
        System.out.println("\tthis     = "+this); //add this
        System.out.println("\tobj      = "+obj);  //add this
        System.out.println("\tobj.v[0] = "+obj.v[0]);
        System.out.println("\tv[0]     = "+v[0]);
        System.out.println("\tobj.v    = "+obj.v);
        System.out.println("\tv        = "+v);
    }
    public static void main (String[] args)
    {
        tryClass obj = new tryClass();
        int[] v = new int[1];
        obj.v[0] = 40;
        System.out.println("In main(), BEFORE running met()");
        System.out.println("\tobj      = "+obj); //and this
        System.out.println("\tobj.v[0] = "+obj.v[0]);
        System.out.println("\tobj.v    = "+obj.v);
        obj.met();
        System.out.println("\nIn main(), AFTER running met()");
        System.out.println("\tobj      = "+obj); //and also this
        System.out.println("\tobj.v[0] = "+obj.v[0]);
        System.out.println("\tobj.v    = "+obj.v);
    }
}

You could also create a constructor for the class too:

public tryClass() {
    System.out.println("Creating new instance of tryClass!");
}

to see what is going on...

(Or alternatively, as a learning experience, you could check out the debugger in your IDE. That will come in handy a lot...)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top