3

Trying to fully grasp Java's pass-by-value. Let's say we have this code:

public class Test {

    static void switchIt(Test t) {
        t = new Test();
    }

    public static void main(String ... args) {
        Test a = new Test();
        switchIt(a);
    }
}

When the object referenced by a gets passed to switchIt(), the reference value is copied to t. So we'd have two different reference variables, with identical bit-patterns that point to a single object on the heap.

When t = new Test() runs, obviously a still refers to the old object, and t now points to a new object on the heap. Since the a and t reference variables used to have identical bit-patterns, does this mean that Java implicitly changed the bit-pattern of the t reference variable? Or is it wrong to assume that the bit patterns were ever identical to begin with?


Let's say the a reference variable is represented on the stack as 0001. When I pass it to the function, that means t is also represented on the stack as 0001, since I passed a copy of the bits in the reference variable.

When I assign t to a new Test(), if t and a both are represented as 0001 on the stack, would that 0001 change for t?

MackieeE
  • 11,751
  • 4
  • 39
  • 56
ev0lution37
  • 1,129
  • 2
  • 14
  • 28
  • 1
    "Since the a and t reference variables used to have identical bit-patterns, does this mean that Java implicitly changed the bit-pattern of the t reference variable?" It's not clear what you mean by that. You're simply assigning a new value to the variable... what difference does it make what the previous value was? – Jon Skeet Sep 23 '15 at 16:57
  • Edited to try to clarify. I might just have a misconception of how reference variables are represented on the stack. – ev0lution37 Sep 23 '15 at 17:01
  • This doesn't have anything to do with garbage collection, does it? – async Sep 23 '15 at 17:20

4 Answers4

2

Think of it this way:

Java isn't passing the object, it's passing the memory pointer of the object. When you create a new object, it gets a new pointer. So when we say java always passes by value, it's because it's always passing the pointer of the object which is a numeric value.

Even though the objects are equal to one another (a.equals(t)) may return true - they are not identical because they have different pointers and are thusly different objects residing in different memory space.

Using your edit example. a would have 0001 but t would be 0002

Is Java "pass-by-reference" or "pass-by-value"?

Hope that helps

Community
  • 1
  • 1
bsautner
  • 4,479
  • 1
  • 36
  • 50
  • Perfect. Got it now. So Java does create a new pointer and a new object, which would be eligible for GC after the switchTo() method ran. – ev0lution37 Sep 23 '15 at 17:05
2

Yes, the reference for t would change to point to the newly-allocated Test instance. Your understanding is correct on that point.

When the switchIt() method returns, there are no longer any references to that new object. It is now eligible for garbage collection, while the original object that a continues to reference will not be collectible until main() returns.

erickson
  • 265,237
  • 58
  • 395
  • 493
1

I think you got it, but you didn't phrase it too well. Here's a more in depth explanation, though the implementation may not be 100% exactly as I'm describing.

When you compile that code, a structure called a "stack frame" will be created for each of your methods. Each stack frame will hold enough space in it for parameters, local variables and so on. Basically it will have enough resources for your method to do its thing. All these stack frames are placed in "the stack" :)

When you run your code, in main you create a new instance of Test and assign the reference to variable a or, more precisely, to the location in the stack frame reserved for variable a. The actual object will be stored on the heap and your variable a will only hold the memory address of that object, as you already seem to know.

When you call switchIt, the runtime will send a copy of the reference a to the stack frame of the method switchIt. This stack frame has enough space for your parameter and it will store it in its reserved space. But what you're doing in switchIt is replacing the initial value stored in that reserved space with a new reference from a new object that has just been created and placed on the heap. Now you have two objects on the heap, each stack frame containing one of these references.

async
  • 1,537
  • 11
  • 28
1

I think the code will clear you more .Check the hash code in each print statement it is not the memory location but it will help you to understand the answer of your question.


class Ideone
{
 static void switchIt(Ideone t) {
     System.out.println("Object t "+t); // print statement 2
        t = new Ideone();
     System.out.println("object t after changing t "+t);  // print statement 3
    }

    public static void main(String[] args) {
        Ideone a = new Ideone();
        System.out.println("object a "+a);    // print statement 1
        switchIt(a);
        System.out.println("object a after calling switchIt() "+a); // print statement 4
    }
}

Output:

object a Ideone@106d69c
Object t Ideone@106d69c
object t after changing t Ideone@52e922
object a after calling switchIt() Ideone@106d69c

print statement 1,2,4 have same hash code but 3 has different hash code.


1. Creating object a


creating object a


2. Passing a to switchIt(Ideone t):


Paasing a to switchIt()


3. Changing t to new Ideone():


changing t to new value

Note:The hash code are not actual memory location.

singhakash
  • 7,891
  • 6
  • 31
  • 65