• Post Reply Bookmark Topic Watch Topic
  • New Topic

How to recognize that String is an immutable object while StringBuffer not?  RSS feed

 
Luk Cora
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I undesrtand that String is immutable, so every change applied after an instatation of a variable will create a new Object, while StringBuffer is mutable and can alter the object itself.
But relying on the official documentation, how i can guess this behavior?
According to javadoc, both classes are final, and there are't noticable "keywords" that explain me: String=immutable - StringBuffer=mutable

What is the core concept at base of which every alteration of the String object cause the instatation of a newly object? And viceversa for StringBuffer.
 
Les Morgan
Rancher
Posts: 768
19
C++ Java MySQL Database Netbeans IDE Oracle Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I go by this general rule of thumb: read the API.

From the Java String API: "The String class represents character strings. All string literals in Java programs, such as "abc", are implemented as instances of this class.

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example: ..."

Luk Cora wrote:I undesrtand that String is immutable, so every change applied after an instatation of a variable will create a new Object, while StringBuffer is mutable and can alter the object itself.
But relying on the official documentation, how i can guess this behavior?
According to javadoc, both classes are final, and there are't noticable "keywords" that explain me: String=immutable - StringBuffer=mutable

What is the core concept at base of which every alteration of the String object cause the instatation of a newly object? And viceversa for StringBuffer.
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
StringBuffer extends AbstractStringBuilder class which uses char value[] instance variable. This is the variable where value of a string is stored
and it is not final. So when we call append then values are appended no new object created.

In String, it doesn't extends any class and uses final char value[] instance variable. So it can't be replaced and hence every time new instance
will be created whenever append is called.
 
Campbell Ritchie
Marshal
Posts: 55781
164
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tushar Goel wrote:. . . In String, it doesn't extends any class
You sure about that? What about Object?
[String] uses final char value[] instance variable. So it can't be replaced . . .
But arrays are always mutable, so it is in theory possible to alter part of the String without reassigning the value array.If you go through the methods of String, you won't find any which alter the current object. No setXXX methods. If you read about StringBuilder, all the methods say how they modify the current object.
 
Campbell Ritchie
Marshal
Posts: 55781
164
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The core concept is that the original plan was for Strings to be shred, and for String literals to be cached and reused. That is only possible if Java® Strings are immutable. However the data are stored, whether in an array or some other sort of data structure, all methods of altering that data structure are avoided.
There is also a principle of design that one should consider providing a mutable counterpart of an immutable class. In the case of String, that is StringBuilder (previously they used StringBuffer); the two classes are designed to work together. If I were designing the String class, this is how I would implement String#catenate():-
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By default Object class is extended by every class so i thought not to mention it..

I got your point about String. As there are no string update methods so we can't modify the values..
 
Paul Clapham
Sheriff
Posts: 22521
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tushar Goel wrote:As there are no string update methods so we can't modify the values..


That's a necessary condition for an object to be immutable, sure. But it isn't sufficient. Consider the case when a class with no "update" methods has a getter method which returns part of an object's state which is mutable. Like this:



No update methods, right? Next consider this code:



I believe that most designers wouldn't call that "immutable".
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes agree...
 
Paul Clapham
Sheriff
Posts: 22521
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So then we would have to make sure that no String method returns a mutable object which could be mutated in order to alter the String object's internal state, right? That's a bit more difficult. There are several methods which return byte[] or char[] or String[], and all arrays are mutable. But when we examine the description of those methods we can see that mutating any of those arrays doesn't modify the String itself.
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
returns a mutable object which could be mutated in order to alter the String object's internal state, right?

Right

But when we examine the description of those methods we can see that mutating any of those arrays doesn't modify the String itself.

So i suppose they are returning new object instead of same object. Also, they might be using copy of it instead of using original..
 
Paul Clapham
Sheriff
Posts: 22521
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Tushar Goel wrote:So i suppose they are returning new object instead of same object. Also, they might be using copy of it instead of using original..


Exactly. For example the split() methods return an array of Strings which represent the original String broken up into pieces, more or less. It's pretty clear that modifying that array doesn't modify the original String. It's a new object. The toCharArray() is more suspicious, since it returns an array of characters which looks a lot like something which might be stored inside a String object. But the documentation is clear: it says "Converts this string to a new character array." So that would be a copy.
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you..
 
Campbell Ritchie
Marshal
Posts: 55781
164
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's a pleasure
This is one way you can implement a certain String method to maintain immutability:-Find a copy of Effective Java™ by Joshua Bloch (page 184) and you will find he calls that a defensive copy. In fact you should take defensive copies of any mutable reference type whenever it enters or leaves your object.

As previously mentioned, another feature necessary for immutability is that the class be marked final.
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!