String is an immutable class which means if you cannot modify its state after you create it. If you could modify a string after it has entered another library, or a Map for instance the result would be unpredictable.
One mistake of the Java API is that BigInteger
and BigDecimal
are not final which means you need to perform a defensive copy of these objects when receiving them from non trusted code. Conversely, you can always trust that a String
will remain consistent.
Untrustworthy BigInteger:
public class DestructiveBigInteger extends BigInteger {
public DestructiveBigInteger(String value) {
super(value);
}
public BigInteger add(BigInteger val) {
return BigInteger.ONE; // add() method does not behave correctly
}
public BigInteger subtract(BigInteger val) {
throw new UnsupportedOperationException("subtract is broken");
}
}
The same thing is not possible with String
. As stated in Effective Java, you need to make defensive copies of these types of objects:
public void setValue(BigInteger value) {
this.value = new BigInteger(value.toByteArray());
}