Skip to content

Immutable class while using a cache

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);
}
}

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.