chepaiytrath
chepaiytrath

Reputation: 718

How is immutability actually implemented in String class and mutability in StringBuffer and StringBuilder in code?

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:

  1. setLength which called the same named setters of parent AbstractStringBuilder.
  2. setCharAt which manipulated the char value[] of parent AbstractStringBuilder.

Upvotes: 1

Views: 770

Answers (3)

dimo414
dimo414

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

TheLostMind
TheLostMind

Reputation: 36304

There are a lot of things here.

  1. All fields are private.
  2. There are no setters / mutators.
  3. Construction injection of arguments (using which String has to be constructed).
  4. Reference to underlying char array (char[] value) does not leak out of this class.

Upvotes: 2

Robby Cornelissen
Robby Cornelissen

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

Related Questions