While going through JCIP
, I came across the below code snippet which was considered as Immutable
. However the explanation provided makes me confused.
OneValueCache wouldn’t be immutable without the copyOf calls in the constructor and getter. Arrays.copyOf was added as a convenience in Java 6; clone would also work.
Aren’t the state vars
of OneValueCache
themselves Immutable
with final
and BigInteger
being itself immutable
? Why do we need to have Arrays.copyOf
if the state of OneValueCache
is already Immutable
?
class OneValueCache { private final BigInteger lastNumber; private final BigInteger[] lastFactors; public OneValueCache(BigInteger i, BigInteger[] factors) { lastNumber = i; lastFactors = Arrays.copyOf(factors, factors.length); } public BigInteger[] getFactors(BigInteger i) { if (lastNumber == null || !lastNumber.equals(i)) return null; else return Arrays.copyOf(lastFactors, lastFactors.length); } }
Advertisement
Answer
The final
applies to lastFactors
, but not to the elements of lastFactors
. If the methods returned lastFactors
directly without copying it, the caller could modify the elements of lastFactors
without any problems, changing the internal state of OneValueCache
. With the copy operations, the returned arrays are copies of the final variable, and any modifications will modify the copy of the array, not the immutable instance.