1

As I'm relatively new to Java, i'm still not sure about the basic pass-by-value/pass-by-reference thing. I've read this question on SO: Is Java “pass-by-reference” or “pass-by-value”?, which seems to have some very good answers. One of the articles referenced in one such answer was Java is Pass-by-Value, Dammit!.

After reading the answers, and the article, I thought:

  1. Everything in Java is pass by value, there's no pass by reference (follows from the readings).
  2. Primitives are always passed by value (my thought)
  3. Objects are passed by reference (my thought)
  4. The point above(3) is actually wrong and Object references are passed by value (follows from the article).

So now, I'm struggling between points 3 and 4. I wrote this simple class to clear things a bit:

package Chap_1;

/**
 * Created by user1 on 7/18/15.
 */
public class JavaTest1 {

    private double balance;

    public JavaTest1(double amt) {
        balance = amt;
    }

    public double getBalance() {
        return balance;
    }

    public void method1() {
        JavaTest1 obj1 = new JavaTest1(300.00);
        System.out.println("Balance in method1 before method2= " + obj1.getBalance());
        method2(obj1);
        System.out.println("Balance in method1 after method2 = " + obj1.getBalance());
    }

    public void method2(JavaTest1 o) {
        o.balance -= 100.00;
    }

    public static void main(String[] args) {
        JavaTest1 j1 = new JavaTest1(500.00);
        System.out.println("Balance in main before= " + j1.getBalance());

        j1.method1();
        System.out.println("Balance in main after = " + j1.getBalance());

    }
}

With this code, I get the output:

Balance in main before= 500.0
Balance in method1 before method2= 300.0
Balance in method1 after method2 = 200.0
Balance in main after = 500.0

My observations are:

  1. In main, things get started with one JavaTest1 object j1, with a starting balance of 500. j1 then calls method1().
  2. In method1(), another JavaTest1 object is created, with starting a balance of 300. method1() then calls method2().
  3. In method2(), an object of type JavaTest1 is passed. This method then deducts 100 from the balance of the object reference that was passed to it.
  4. When I run the code, I see that the balance of the object created in method1 is reduced to 200 in method2().

Now this is where my confusion lies. If object references are passed as values, then the balance deduction in method2() should not have modified the object created in method1(). But since it did modify the balance, doesn't it essentially say that objects are always passed as references, proving that both method1() and method2() operate on the same object. Otherwise, method2(JavaTest1 o) should have created another object of type JavaTest1 with it's reference being called o.

Community
  • 1
  • 1
Manish Giri
  • 3,562
  • 8
  • 45
  • 81
  • The answers in the duplicate already cover all the points you're confused about. Read them (all) again. – Sotirios Delimanolis Jul 18 '15 at 23:33
  • @DavidWallace Buzzkill! Please post it there. – Sotirios Delimanolis Jul 18 '15 at 23:35
  • @DavidWallace I posted an answer there a while back. It's gotten some attention. You can do it too. – Sotirios Delimanolis Jul 18 '15 at 23:37
  • Here, have an upvote. – Dawood ibn Kareem Jul 18 '15 at 23:41
  • @DavidWallace Community wiki :) – Sotirios Delimanolis Jul 18 '15 at 23:41
  • @SotiriosDelimanolis: it would have been really helpful to me to get all my doubts clarified in my question with my own example, rather than having to scour through a question which I have already read and re-read again a gazillion times. If I had understood everything there in the first place, I would have not asked this question. I don't think it would have hurt a lot to wait a while before closing this question as a duplicate one. Perhaps DavidWallace's answer would have been just the info. I needed. – Manish Giri Jul 18 '15 at 23:44
  • [Read this one.](http://stackoverflow.com/a/12429953/438154) It has drawings and everything, illustrating what references are and how they are used. – Sotirios Delimanolis Jul 18 '15 at 23:46
  • The key point is that objects are NEVER passed anywhere in Java. They are not passed by reference. They are not passed by value. They stay exactly where they are first created and are NEVER passed. The things that are passed to a method are the VALUES OF EXPRESSIONS. And the value of an expression can be one of three things. (1) It can be a PRIMITIVE value. (2) It can be NULL. (3) It can be a REFERENCE to an object. Those are the only three things that the value of an expression can be. A variable by itself is also an expression; so those are also the only things that the value of ... – Dawood ibn Kareem Jul 19 '15 at 00:35
  • ... a variable can be. A method argument can be one of those three things. A PRIMITIVE value, NULL, or a REFERENCE to an object. Oh, and it's always passed to the method BY VALUE. So you can NEVER pass an object; but you CAN pass a reference to an object. And you pass it by value. – Dawood ibn Kareem Jul 19 '15 at 00:36

3 Answers3

0

Actually this problem is simply caused by a misunderstanding of statement 3 and 4. "Objects are passed by reference" means that if an object is used as argument for a method, a reference to the object will be passed to the method - think of this reference as an int with a specific meaning. "Object references are passed by value" means that the reference itself will be passed by value. These two don't exclude each other.

  • By "Object references are passed by value means that the reference itself will be passed by value", do you mean to say that if a reference to an object is stored at memory address 42, then **reference itself will be passed by value** just says that the memory address 42 will be copied over to the argument (which in other words is pass by value) to the second method? – Manish Giri Jul 18 '15 at 23:17
  • Yes, in that case the value stored at address 42 would be copied over to the argument. And that value would be a reference to the object. – Tesseract Jul 18 '15 at 23:24
  • If for example you wanted to translate a Java program to C, you could represent each object as a struct and each object variable would be a pointer to a struct. Those pointers would then be passed by value when calling functions. – Tesseract Jul 18 '15 at 23:28
0

Though objects appear to be passed by reference, the way it really works is that references to objects are passed by value. You can tell the difference if, within a function, you change a formal parameter of an object type to another object (or to null) -- the actual parameter passed by the caller won't change, in other words the caller won't see the assignment.

(If the caller were to see an assignment to a formal parameter in a called function that would be representative of pass by reference. For example, C# has out and ref parameters for these purposes.)

Erik Eidt
  • 23,049
  • 2
  • 29
  • 53
0

Okay, let's think this out a bit. At this line:

JavaTest1 j1 = new JavaTest1(500.00);

you create a JavTest1 object and save a reference to it (a pointer to it, essentially) in j1. The balace is 500.00 as you expect.

Then you call method1:

j1.method1();

Inside method1 you create a new JavaTest1object obj and set its balance to 300.00. Notice that this is a whole new object, with its own balance.

When you call method2 you're doing so on the object you created, obj. You subtract 100.00 from the balance, and sure enough the balance is 200.00.

You then return from that method and

System.out.println("Balance in main after = " + j1.getBalance());

prints out the balance from j1 -- *which hasn't been touched by anything and so is still 500.00.

The key here is that you have two separate objects, Call by value or reference doesn't matter, because you simply have two completely separate objects.

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • While I agree and am also aware that there are two completely different objects in this program, I'm concerned instead with the object/objects involved in the two methods `method1()` and `method2()`. Of course, the balance property of object `j1` doesn't have anything to do with the balance of the object created in `method1()`. I was looking for an explanation of how the objects used in `method1()` and `method2()` relate with each other. – Manish Giri Jul 18 '15 at 23:25
  • There's only one object. A Java reference is like an address. When you create the object, obj1 is a reference to an address, say 0x42, where the object was constructed. When you call method2, you pass (by value) that address, and give that copied address the name `o`. When you subtract from `o.balance` Java finds that object at address 0x42, find the balance field, and subtracts. – Charlie Martin Jul 19 '15 at 14:17