General question about the String class - and final classes in general.

I have been reviewing the ideas behind the String class, I don't have a question I need help with so much as I want to summarize my understanding to see if I have it right.

1. A string is an object, an instance of the String class.
2. Strings are immutable, A string object cannot change, you can only change the reference to a new object.
3. Even though a string is an object, it doesn't follow the usual rules of "pass by reference to a method" to a method, because whatever happens in the method, the original String object does not change.
4. You cannot extend the String class.

So these are undisputable properties of strings. Now it would seem logical to suggest that all of this happens because the String class is declared with the keyword final, agreed?

I have seen it written that a final class cannot be extended, but final seems to imply more than just that, it would seem that final means points 2, 3, 4. ?

There is no such thing as "pass by reference" in Java. Strings follow the usual rules about behaviour when they are passed as arguments, but their behaviour is circumscribed by their beign immutable.
A class marked final cannot be inherited from. That is why the String class has the final modifier. If you have an immutable class, it might be possible to inherit from it and create new classes with mutable fields, so you could have an instance of the immutable class Foo which is actually mutable.
To make classes immutable, all their fields should be final, there should be no methods which can alter the state of their mutable reference-type fields, and any methods returning these mutable reference-type fields should return a copy.

I hope that helps.

Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679

posted Jul 18, 2009 10:28:58

0

Campbell Ritchie wrote:There is no such thing as "pass by reference" in Java. Strings follow the usual rules about behaviour when they are passed as arguments, but their behaviour is circumscribed by their beign immutable.
A class marked final cannot be inherited from. That is why the String class has the final modifier. If you have an immutable class, it might be possible to inherit from it and create new classes with mutable fields, so you could have an instance of the immutable class Foo which is actually mutable.
To make classes immutable, all their fields should be final, there should be no methods which can alter the state of their mutable reference-type fields, and any methods returning these mutable reference-type fields should return a copy.

I hope that helps.

Yes it helps, in that sense that you are saying that to make an object immutable it seems to require more than just making the class itself final.

As for your comment, "there is no such thing as pass by reference in java", well I guess we are talking about semantics here, I only used the phrase to mean that when an object is an argument in a method call, in reality you are passing a reference to the object. As opposed to pass by value when using primitives as argument.

But I suppose that might not be relevant. The real question what is it about a String object that makes the original unchangeable by a method call. You answer seems to suggest that it is immutability property of strings, and further more this immutability can not be ascribed solely to the fact that the class is described as final.

Final modifier makes a class strong immutable but other way to make class immutable is don't make class final, make all the method in the class as final. Now think about the case where a immutable class is extended by another class which has added some fields which are mutable then the extended class is mutable though original contract is still immutable. So making class final is preffered way of making a class immutable. But making class final is not the only thing which makes class immutable there are other things to be taken care of
1. It should not have any setter.
2. It should have its field primitive as for as possible.
3. If it has fields which are mutable then getter or any method should not return reference to those field rather they should return copy of these fields.

Strings are quite easy to make immutable because they only have one field, and that can be kept well hidden from prying eyes. For classes with several mutable fields that is awkward. If a mutable object is passed to a supposedly immutable object's constructor, it is possible for references to that object to remain elsewhere, which can change its state. So it may be necessary to coy objects in the constructor of an immutable class.

Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679

posted Jul 18, 2009 12:31:54

0

Thanks Campbell, and also shivendra. Your comments cleared up a few things for me. On we go.

It is more then semantics, but the confusion is a result of the unfortunate decision to call them references. What they really are is implicit pointers. Pointers that hide the pointer arithmetic away from the programmer.

Java is pass by value, always. That value can be a primitive or an address(or whatever other representation that the JVM uses) of the object. Most common languages only support pass by value, except c++ which supports both.

"Computer science is no more about computers than astronomy is about telescopes" - Edsger Dijkstra

Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679

posted Jul 18, 2009 13:06:10

0

Rusty Shackleford wrote:It is more then semantics, but the confusion is a result of the unfortunate decision to call them references. What they really are is implicit pointers. Pointers that hide the pointer arithmetic away from the programmer.

Java is pass by value, always. That value can be a primitive or an address(or whatever other representation that the JVM uses) of the object. Most common languages only support pass by value, except c++ which supports both.

Duly noted.If it's not semantics, call it terminology. I understand the mechanics perfectly, it's the terminology that isn't so clear. Yes it's pass by value, but in the case of object as argument the value being passed is a reference (or pointer or whatever) to the data (object) and not the actual value of the data. There is only one version of the object, but two 'pointers' to the same object, which is why normally an 'original' object can be changed by a method but an original primitive can't.

My initial mistake was in ascribing the unchangeability of strings as being an exception to the rules of object "pointers" as arguments, when really it is about the properties of the object itself.