Frage

int i = 0;
int j = i;
System.out.println("initial int: " + j); // 0

Integer ii = new Integer(0);
Integer jj = ii;
System.out.println("initial Integer: " + jj); // 0

String k = new String("s");
String l = k;
System.out.println("initial String: " + l); // "s"

Person person1 = new Person("Furlando"); // from constructor -> publ. instance var. 'name'
Person person2 = person1;
System.out.println("initial Person: " + person2.name); // "Furlando"

/*--------------------*/
System.out.println();
/*--------------------*/

i += 1;
System.out.print("added 1 to int: [" + i);
System.out.println("], and primitive which also \"refers\" to that (has a copy, actually), has a value of: [" + j + "]");

ii += 1;
System.out.print("added 1 to Integer object: [" + ii);
System.out.println("], and object which also refers to that, has a value of: [" + jj + "]");

k += "tring";
System.out.print("added \"s\" to String object: [" + k);
System.out.println("], and object which also refers to that, has a value of: [" + l + "]");

person1.name = "Kitty";
System.out.print("changed instance variable in Person object to: [" + person1.name);
System.out.println("], and object which also refers to that, has a value of: [" + person2.name + "]");

/* [COMPILER OUTPUT]
    initial int: 0
    initial Integer: 0
    initial String: s
    initial Person: Furlando

    A) added 1 to int: [1], and primitive which also "refers" to that (has a copy, actually), has a value of: [0]
    B) added 1 to Integer object: [1], and object which also refers to that, has a value of: [0]
    C) added "s" to String object: [string], and object which also refers to that, has a value of: [s]
    D) changed instance variable in Person object to: [Kitty], and object which also refers to that, has a value of: [Kitty]
*/

I understand A, we have a primitive there; no references. By-copy.
I hoped B and C would behave the same way as D - change according to the reference they were given.

Why this object-reference-to-another-object only "works" with user defined objects, not Integers, Strings, etc.?



Thank you all for your answers - now I get it!

War es hilfreich?

Lösung

String and Integer objects are immutable in Java. When you do: ii += 1 or k += "tring" you create new objects. The variables jj and l points to the old objects. That's why you see different values.

Andere Tipps

This behaviour is not about user defined Objects vs. internal but the fact, that "Integer" and "String" (and all other primitive wrapper) objects are handled very special. Integer is just a "wrapper" around a primitive integer and thus the behaviour of it is not a truly a "reference type" one. All those wrapper objects are implemented immutable - the same reference to a Integer will never have another value.

On a side note: Those wrapper objects are casted automatically to primitive types if necessary, therefore they are slower in general usage. The benefit of them are, that they can be null which is sometimes nice.

This to do with the working of the += operator.

What you are really doing is reassigning the value when you call +=

Integer i = 1;
Integer j = i;
i = i + 1;

So now i is pointing to another Integer equal to 2 and j is still pointing to the original Integer equal to 1.

The same goes for your String example.

In your object case you do not change the pointer you change the internal state of the object. Therefore both person1 and person2 point to the same Person.

If you did

Person person1 = new Person("Alice");
Person person2 = person1;
person1 = new Person("Bob");

Then it should be obvious that person1 is now a different Person.

1)Strings and Wrappers(Integer, Long..) are immutable objects and 2)Person is a mutable object and you modified it's properties and since person1 and person2 points to the same reference the changes are applied in both objects.

(immutable - once you have created you can't change it's state)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top