0

Please review the following code:

public class St1 {

    public static void main(String[] args) {

        Boolean b = true;

        C1 c1 = new C1(b);
        C2 c2 = new C2(b);

        System.out.println(c1.getB());
        System.out.println(c2.getB());
    }
}

public class C1 {

    private Boolean m_b;

    public Boolean getB() {
        return m_b;
    }

    public C1(Boolean b) {

        m_b = b;

        m_b = false;

    }

}

public class C2 {

    private Boolean m_b;

    public Boolean getB() {
        return m_b;
    }

    public C2(Boolean b) {

        m_b = b;
    }
}

So the output is:

false
true

But I fail to understand why? All I do is passing and modifying a Boolean object which means I pass its reference or address value. Assignments of objects are also references assignments, aren't they?

So, I understand that I am dealing all the time with the same object. Probably I am wrong. But where? Why changing its value in C1 doesn't affect its value in C2?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
dushkin
  • 1,939
  • 3
  • 37
  • 82
  • When you pass an argument to a method you are passing a new instance of that object. – Cardinal System Jul 09 '17 at 12:28
  • 4
    @CardinalSystem No, that is not how it works. – Mark Rotteveel Jul 09 '17 at 12:29
  • 1
    Which line do you not understand? And why accept a parameter in the `C1` constructor if you're just going to set `m_b` to false anyway? Note that you're not modifying the `Boolean` object at all... – Jon Skeet Jul 09 '17 at 12:29
  • 2
    `"Assignments of objects are also references assignments, aren't they?"` - When you pass an object to a method, you're essentially creating a new variable on the stack which points to that same object in memory. But when you assign a new value to that variable, you're only modifying what that variable points to. You're creating a second object in memory and pointing the variable to that. So the variable outside the method (on a different stack frame) still points to the first object, and the variable inside the method now points to a new object. – David Jul 09 '17 at 12:31
  • @JonSkeet Because I want to be able to change the same value in two classes – dushkin Jul 09 '17 at 12:31
  • Thank you all guys for clarifications – dushkin Jul 09 '17 at 12:32
  • 1
    @dushkin: Think of if this way, when you're inside the method that received the value... `arg.setValue(123)` - This modifies the object to which `arg` points in memory. `arg = new SomeObject(123)` - This does not modify the original object, but creates a new one and points `arg` to it. – David Jul 09 '17 at 12:33
  • @David So, according to your explanation, m_b = false; is like m_b = new Boolean(false)... , because a m_b is being allocated as a new object. Right? Is there a way to overcome it? – dushkin Jul 09 '17 at 12:45
  • 1
    @dushkin: That's correct. And what do you mean by "overcome it"? This is by design. You could wrap your boolean value in an object and set the value on the object within the method, ending up with something like: `arg.setValue(false);` – David Jul 09 '17 at 12:46
  • @David Can you please explain to me again why when I assign 'false' to m_b on Class C1 C-tor, m_b turns to point to a new object? – dushkin Jul 11 '17 at 14:03
  • @dushkin: Because the literal "false" is itself a new instance of a boolean primitive. The variable just points to whatever you point it to. On the first line of that constructor you point it to the same in-memory object as the variable received as a parameter. On the second line, you point it to a new instance. At no point do you modify any existing instances, you're just changing what the variables point to. – David Jul 11 '17 at 14:20
  • @David Much clearer now! Thank you so much! – dushkin Jul 11 '17 at 14:24

0 Answers0