1

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.
dimo414
  • 47,227
  • 18
  • 148
  • 244
chepaiytrath
  • 678
  • 1
  • 9
  • 20
  • The strange things about "setters" is that they don't need to be called "set", `StringBuilder` has `append` methods which you use to modify it's internal state, not "strictly" setters, cause they don't change the state from one state to another, but simply modify the current state, so I guess you could call them "modifiers" instead – MadProgrammer Sep 03 '15 at 04:32
  • 1
    @MadProgrammer - I believe *mutators* would be the right word :) – TheLostMind Sep 03 '15 at 04:34
  • 1
    @TheLostMind Meh, I like modifiers, cause I be simple ;) – MadProgrammer Sep 03 '15 at 04:42
  • 1
    @MadProgrammer - LOL.. We should be thinking alike.. I have lost my mind and your name is.... :P..Ya, `modifiers` would work :) – TheLostMind Sep 03 '15 at 04:44

3 Answers3

4

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.

Community
  • 1
  • 1
dimo414
  • 47,227
  • 18
  • 148
  • 244
2

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.
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
0

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.

Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156