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.