0

i'm already tired but i'm wondering if (see the topic).

String a = "first";
    String b = "second";
    a = b;
    b = "third";
    System.out.println(a + ", " + b);

-my question is why i got the output: "second, third". Isn't is String referenced type? So after command "a = b;" why didnt change both of variables? Wasn't both variables referencing to the same object? (or the same String from the String pool?)

Charlie Harper
  • 379
  • 4
  • 7
  • 21
  • If you did `Foo a = new Foo(3); Foo b = new Foo(4); a = b; b = new Foo(5);`, would you expect `a` to be altered by the final line? – Oliver Charlesworth Apr 19 '14 at 18:54
  • 2
    [Is Java pass-by-reference?](http://stackoverflow.com/questions/40480/is-java-pass-by-reference) – Sotirios Delimanolis Apr 19 '14 at 18:55
  • First fact that you should consider is `String is an immutable type`. – mostruash Apr 19 '14 at 18:57
  • 1
    @mostruash No, that has absolutely nothing to do with it. This is all about references. – Sotirios Delimanolis Apr 19 '14 at 18:57
  • @SotiriosDelimanolis It absolutely has something to do with it. If `String` is immutable, than the assignment operator must initialize a new instance of the String class because there is NO other option if String is immutable (you get the point, I won't go into detailed analysis of how JRE handles strings). – mostruash Apr 19 '14 at 19:05
  • @mostruash I think you're confusing things. Immutability is unrelated to the assignment operator. If `String` was mutable, this question and its answer would be the same: changing the value (the reference) that one variable holds does not change the value of any other variable. – Sotirios Delimanolis Apr 19 '14 at 19:10
  • @SotiriosDelimanolis If String was mutable, the answer would be the same. But if you assume that String is immutable, you can conclude that it's impossible to expect both `a` and `b` (after `a = b`) to refer to the same string of characters after executing `b = "third"`. The reasoning behind it is in my previous comment. What I meant is you can find the answer to this question without going into reference types. – mostruash Apr 19 '14 at 19:14
  • 1
    @mostruash They're just two unrelated things. The assignment operator works the same for immutable types as it does for mutable types. Exchange `String` with any other type, the result is the same. – Sotirios Delimanolis Apr 19 '14 at 19:20
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/51037/discussion-between-mostruash-and-sotirios-delimanolis) – mostruash Apr 19 '14 at 22:41

3 Answers3

0

Isn't is String referenced type?

Yes, String is a reference type.

So after command "a = b;" why didnt change both of variables?

Because you only said to change the value of one variable at a time.

This statement:

b = "third";

only changes the value of b. It changes it to refer to a different string. The value of a remains as it was before - a reference to a string with contents "second".

It's very important to distinguish between these concepts:

  • Variables
  • Values
  • References
  • Objects

When you write:

a = b;

That just means "take the current value of b, and make it the new value of a." It doesn't say "make a and b equivalent variables, so that any change to the value of either variable affects the other variable". When you change the value of b in the next line to refer to a different object, that does nothing to either a or the object that the value of a refers to.

Now I suspect you were being confused because of code like this:

StringBuilder a = new StringBuilder();
StringBuilder b = a;
a.append("foo");
System.out.println(b); // Prints foo

In this case the a.append() call doesn't change the value of a or b at all... both variables still have values which refer to the same StringBuilder object. The append method instead changes the data within that object... so when you print the contents of the object in the final line, getting at it via b, you still see foo because you're still referring to the same (modified) object.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • yes of course i didnt mean a= b; but b = "third"; I'm very tired of this for now i must take a break, thanks. – Charlie Harper Apr 19 '14 at 18:57
  • @CharlieHarper: The rest of my answer still applies. Changing the value of `a` doesn't change the value of `b`, or vice versa. – Jon Skeet Apr 19 '14 at 18:58
0

So after command "a = b;" why didnt change both of variables?

Variables for reference types "refer to" objects. That is, reference variables hold a reference value. (A reference value can be thought of as an opaque number or handle, such that it uniquely identifies an object.)

However, variables are not references (in an "alias/C++" sense) themselves and each variable holds an independent, but possibly duplicate, value. Thus the assignment only affects - as in, assigns a new [reference] value - to the particular variable while it leaves the values stored in all other variables alone.

user2864740
  • 60,010
  • 15
  • 145
  • 220
0

Yes, a and b are both referencing the same string in the pool after a=b:

         String pool
             "first"                

[a] -------> "second"
                ^
[b] ------------|             "third"

However, the re-assignment of b does not affect the reference stored in a, as they are two distinct local variables that can reference different (immutable as always) strings. You will see:

         String pool
             "first"                

[a] -------> "second"

[b] ------->  "third"
nanofarad
  • 40,330
  • 4
  • 86
  • 117