Reputation: 718
I know the prerequisites for a class to be made immutable. I looked into the code, there were no setters for any variable defined in String
. For StringBuffer
and StringBuilder
, there were two setters:
setLength
which called the same named setters of parent AbstractStringBuilder
. setCharAt
which manipulated the char value[]
of parent AbstractStringBuilder
.Upvotes: 1
Views: 770
Reputation: 48864
String
is "immutable" because its API (the public methods it defines) provides no way for a caller to change its state. Other classes, like StringBuilder
, are mutable because they do provide "mutators", or methods that change the state of the class.
Under the covers there's nothing different between mutable or immutable objects. An object is just the primitive and reference values that make up its fields, and all fields are conceptually mutable (ignoring the final
keyword for the moment). But by restricting the visibility of these fields (e.g. making them private
) and defining methods that limit what a caller can do (like defining a getter but not a setter) you can provide a guarantee that instances of the class will be immutable, which is to say you promise none of its fields (or the objects they reference) will change over its lifetime.
By using the final
keyword you can be even more explicit that a class is immutable. If you simply don't provide mutator methods, it's still possible for a class to be mutable if some private method mutates the class. If all the fields in a class are marked final
, that's not (normally) possible. You can be confident any class with only final
primitive (or immutable) fields is immutable*. That isn't the only way to guarantee immutability, but it is the clearest - any attempt to mutate the class would be a compiler error.
* The class itself also has to be declared final
, otherwise someone could potentially create a mutable subclass. But again, there are other ways to ensure immutability. Using final
everywhere is just the easiest to see.
Upvotes: 4
Reputation: 36304
There are a lot of things here.
- All fields are private.
- There are no setters / mutators.
- Construction injection of arguments (using which String has to be constructed).
- Reference to underlying char array (
char[] value
) does not leak out of this class.
Upvotes: 2
Reputation: 97312
Mutability is not merely defined by the presence or absence of setter/mutator methods.
In the case of StringBuilder
and StringBuffer
, there's a plethora of other methods (e.g. all the append()
methods) that alter the internal state of the object, and hence make it mutable.
Upvotes: 0