If String is immutable, then why does this work?

G

George

Dear All,

My understanding is that String objects are immutable, thus you can not
change them but any changes will be saved in a different object of the
same class.

I have written the following simple programme, that converts the string
Hellow World to upper case and prints it.

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");
str1 = str1.toUpperCase();
System.out.println(str1);
}
}

If str1 is immutable as a String object, then how can we save the results
of the conversion back to the same object? Should that not be a different
one? What am I missing here?

Thanks,
George

Computers are useless. They can only give you answers.
Pablo Picasso (1881-1973)
 
M

Matt Humphrey

George said:
Dear All,

My understanding is that String objects are immutable, thus you can not
change them but any changes will be saved in a different object of the
same class.

I have written the following simple programme, that converts the string
Hellow World to upper case and prints it.

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");
str1 = str1.toUpperCase();
System.out.println(str1);
}
}

If str1 is immutable as a String object, then how can we save the results
of the conversion back to the same object? Should that not be a different
one? What am I missing here?

What you're missing is that str1.toUpperCase () creates a new String object
whose reference is assigned to the variable str1. Variables hold references
to objects--they are not the objects themselves. The String object
previously referred to by str1 is unchanged.

Matt Humphrey (e-mail address removed) http://www.iviz.com/
Cheers,
 
A

Adam Maass

George said:
Dear All,

My understanding is that String objects are immutable, thus you can not
change them but any changes will be saved in a different object of the
same class.

I have written the following simple programme, that converts the string
Hellow World to upper case and prints it.

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");
str1 = str1.toUpperCase();
System.out.println(str1);
}
}

If str1 is immutable as a String object, then how can we save the results
of the conversion back to the same object? Should that not be a different
one? What am I missing here?

The line:

String str1

declares a variable of type "reference to String" named str1.


str1.toUpperCase()

constructs a new String object containing the upper-cased version of the
object referenced by the variable str1, and returns a reference to the new
String.


str1 = str1.toUpperCase()

assigns the new reference to the variable str1.



You are confusing the notion of "object" and "reference to object." While
the values of String objects themselves can't change, the values of the
reference variables pointing at them can.

-- Adam Maass
 
I

IOANNIS

George said:
Dear All,

My understanding is that String objects are immutable, thus you can not
change them but any changes will be saved in a different object of the
same class.

I have written the following simple programme, that converts the string
Hellow World to upper case and prints it.

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");
str1 = str1.toUpperCase();
System.out.println(str1);
}
}

If str1 is immutable as a String object, then how can we save the results
of the conversion back to the same object? Should that not be a different
one? What am I missing here?

Thanks,
George

Computers are useless. They can only give you answers.
Pablo Picasso (1881-1973)


Both replies explain this issue.
It is basically a different object.
Here's a way to find it out.
Use the hashCode() method defined in Object class.
This is a very important method for the JVM. It returns an int that "sort
of" tries to identify uniquely all objects.
The idea is that if two objects are equal according the .equals() method
then they MUST have the same hashCode The opposite doesn't work. You can
have two different objects with the same hashCode() (usually by overriding
the method).
In your code extract you can do this!

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");

System.out.println(str1+str1.hashCode());

str1 = str1.toUpperCase();
System.out.println(str1+ str1.hashCode());
}
}

Here's my sample output:
Hello World-862545276
HELLO WORLD568232580

Ioannis
 
C

Chris Smith

IOANNIS said:
Both replies explain this issue.
It is basically a different object.
Here's a way to find it out.
Use the hashCode() method defined in Object class.
This is a very important method for the JVM. It returns an int that "sort
of" tries to identify uniquely all objects.

Not exactly. String overrides Object.hashCode, so the has code for a
String doesn't say anything about object identity, but rather something
about the contents of the String. For example, the following code:

String a = "Hello";
String b = new String(a);

will create two different String objects, but they will have the same
hash code.

To get some kind of clue, you should use the static method
System.identityHashCode(Object) instead. That will return the IDENTITY
hash code for the object, which is the one that Object.hashCode would
have returned if it were not overridden. As you said, that provides
incomplete information, specifically:

1. If the hash codes are the same, then you don't know anything. The
objects may be the same, or they may be different.

2. If the hash codes are different, then the objects are different.

Of course, you can compare identity more easily and get a deterministic
answer using '=='.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
O

Oliver Wong

IOANNIS said:
George said:
Dear All,

My understanding is that String objects are immutable, thus you can not
change them but any changes will be saved in a different object of the
same class.

I have written the following simple programme, that converts the string
Hellow World to upper case and prints it.

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");
str1 = str1.toUpperCase();
System.out.println(str1);
}
}

If str1 is immutable as a String object, then how can we save the results
of the conversion back to the same object? Should that not be a different
one? What am I missing here?

Thanks,
George

Computers are useless. They can only give you answers.
Pablo Picasso (1881-1973)


Both replies explain this issue.
It is basically a different object.
Here's a way to find it out.
Use the hashCode() method defined in Object class.
This is a very important method for the JVM. It returns an int that "sort
of" tries to identify uniquely all objects.
The idea is that if two objects are equal according the .equals() method
then they MUST have the same hashCode The opposite doesn't work. You can
have two different objects with the same hashCode() (usually by overriding
the method).
In your code extract you can do this!

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");

System.out.println(str1+str1.hashCode());

str1 = str1.toUpperCase();
System.out.println(str1+ str1.hashCode());
}
}

Here's my sample output:
Hello World-862545276
HELLO WORLD568232580

This is a risky test, as it's possible for two different objects to have
the same hashcode. Much simpler is to use the == operator:

<untestedCode>
public class Test{
public static void main(String[] args){
String str1 = "Hello World";
System.out.println(str1 == str1.toUpperCase());
}
}
</untestedCode>

The above should print "false", indicating that they are indeed different
objects. In fact, you can go further and see that when you call
toUpperCase(), the original object was not modified (which is normal, since
it's immutable):

<untestedCode>
public class Test{
public static void main(String[] args){
String str1 = "Hello World";
System.out.println(str1);
System.out.println(str1.toUpperCase());
System.out.println(str1);
}
}
</untestedCode>

The above should print out:

<output>
Hello World
HELLO WORLD
Hello World
</output>

Thus showing that the original String has not been modified.

- Oliver
 
A

Alex Hunsley

George said:
Dear All,

My understanding is that String objects are immutable, thus you can not
change them but any changes will be saved in a different object of the
same class.

I have written the following simple programme, that converts the string
Hellow World to upper case and prints it.

public class Test{
public static void main(String[] args){
String str1=new String("Hello World");


The others have answered well.
I would just like to add: when creating a string, avoid writing:

String str = new String("Hello world");

And instead just write:

String str = "Hello world";

It's shorter and clearer. It also has the advantage that if your code
mentions the same string twice:

String blah = "true";
...
String boz = "true";

.... the compiler will not make two instances of the same string! It will
just have one version of the string "true" floating about, with vars
'blah' and 'boz' both referring to it. This trick is ok for the compiler
to do because strings are immutable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top