Java Reference
In-Depth Information
The
String
class in the Java class library is an example of an immutable class. It uses the caching technique
discussed for the
IntWrapper2
class. The
String
class computes hash code for its content when its
hashCode()
method is called for the first time and caches the value. Thus, a
String
object changes its state internally, but not
for its client. You will not come across the phrase “A
String
object in Java is externally immutable and internally
mutable.” Rather, you will come across the phrase “A
String
object in Java is immutable.” You should understand that
it means
String
objects are at least externally immutable.
Listing 7-18 shows a tricky situation where an attempt has been made to create an immutable class. The
IntHolderWrapper
class has no method that can directly let you modify the value stored in its
valueHolder
instance
variable. It seems to be an immutable class.
Listing 7-18.
An Unsuccessful Attempt to Create an Immutable Class
// IntHolderWrapper.java
package com.jdojo.object;
public class IntHolderWrapper {
private final IntHolder valueHolder;
public IntHolderWrapper(int value) {
this.valueHolder = new IntHolder(value);
}
public IntHolder getIntHolder() {
return this.valueHolder;
}
public int getValue() {
return this.valueHolder.getValue();
}
}
Listing 7-19 has a test class to test the immutability of the
IntHolderWrapper
class.
Listing 7-19.
A Test Class to Test Immutability of the IntHolderWrapper Class
// BadImmutableTest.java
package com.jdojo.object;
public class BadImmutableTest {
public static void main(String[] args) {
IntHolderWrapper ihw = new IntHolderWrapper(101);
int value = ihw.getValue();
System.out.println("#1 value = " + value);
IntHolder holder = ihw.getIntHolder();
holder.setValue(207);
value = ihw.getValue();
System.out.println("#2 value = " + value);
}
}