2

If I create an immutable class. All the fields have to be final. If I use stringbuilder in that like this final StringBuilder s = new StringBuilder("Hello ");

, then the append function can append the value of the s and the class wont be immutable. Please advice.

  • 3
    Not sure why you want a class like StringBuilder as an instance variable? It is mostly created only when needed and then discarded once the string has been built. – Joakim Danielson Sep 17 '19 at 19:59
  • 2
    Since the `StringBuilder` is part of the object, its *state* is part of your objects *state*, and since it can be modified (mutated), it means that your object isn't *immutable* at all. Doesn't matter if it is 99% immutable, if anything can be mutated, then it's **not immutable**. – Andreas Sep 17 '19 at 20:07

1 Answers1

6

It's "shallow-immutable" in that you can't change the fields themselves, but it's not fully immutable - which means you lose pretty much all the benefits associated with immutability.

Basically to achieve immutability, all the constituent parts must either be naturally immutable, or sometimes you can get away with using something which is mutable but a) you constructed it, so nothing else has a reference to it; b) you never expose a reference to it; c) you never mutate it yourself.

For example, you can write an immutable type that uses java.util.Date (although I'd strongly recommend using java.time) - you'd just need to make sure that if you ever wanted to return a date from a method, you cloned it instead of returning the value of the field.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Apparently, [shallow immutable](https://blogs.msdn.microsoft.com/jaredpar/2007/12/04/types-of-immutability/) is a thing; but I think all that phrase can possibly do is confuse people. What benefit is there in applying that label, rather than simply saying _no_ as @Andreas commented. – jaco0646 Sep 17 '19 at 21:17
  • @jaco0646: It's *mostly* useful as a simple way of describing this sort of situation. I don't see any sign that anyone's confused by it though. – Jon Skeet Sep 18 '19 at 05:13
  • 2
    @jaco0646 it’s simply not practical to answer this question with a dogmatic “no”, as then, there’s basically no true immutability in Java. You know, you assume `String` is immutable, but it is just a wrapper around an array and even in the most recent Java version, all arrays are mutable. The same applies to any implementation class backed by an array, say, `BigInteger`, in turn, `BigDecimal`, the immutable collections created via `List.of(…)`, `Set.of(…)`, or `Map.of(…)` when the size is at least three, and so on. – Holger Sep 18 '19 at 14:24
  • So any nontrivial immutable class is likely constructed via the a) to c) recipe of this answer or at least having “naturally immutable” constituent parts which are actually implemented via that recipe… – Holger Sep 18 '19 at 14:26