From the surface, the creation of invariant classes seems to be a good solution. However, once you really need that new type of modified object, you have to work the creation of new objects, and it may involve more frequent garbage collection. For some classes, the problem is not very large. But for other classes (like the String Class), the cost of this scenario is too high.
to solve this problem, we can create a "gay" class and make it modifiable. In the future, as long as involved in a large number of changes in the work can be changed to use the gay class can be modified. When you're done, switch back to the immutable class.
Therefore, the previous example can be changed to the following:
: Immutable2.java//A companion class for making changes//to immutable objects.
Class Mutable {private int data;
public mutable (int initval) {data = Initval;
Public mutable Add (int x) {data = x;
return this;
public mutable multiply (int x) {data *= x;
return this;
Public Immutable2 MakeImmutable2 () {return new Immutable2 (data);
} public class Immutable2 {private int data;
Public Immutable2 (int initval) {data = Initval;
public int Read () {return data;}
public Boolean nonzero () {return data!= 0;}
Public Immutable2 Add (int x) {return new Immutable2 (data + x);
Public Immutable2 Multiply (int x) {return new Immutable2 (data * x);
Public mutable makemutable () {return new mutable (data);
public static Immutable2 modify1 (Immutable2 y) {Immutable2 val = y.add (12);
val = val.multiply (3);
val = Val.add (11);
val = val.multiply (2);
return Val; }//This proDuces the same result:public static Immutable2 modify2 (Immutable2 y) {mutable m = y.makemutable ();
M.add (multiply) (3). Add (one). Multiply (2);
return M.makeimmutable2 ();
public static void Main (string[] args) {Immutable2 i2 = new Immutable2 (47);
Immutable2 r1 = modify1 (I2);
Immutable2 r2 = modify2 (I2);
System.out.println ("i2 =" + I2.read ());
System.out.println ("r1 =" + R1.read ());
SYSTEM.OUT.PRINTLN ("r2 =" + R2.read ()); }
} ///:~
As always, the Immutable2 contains methods that retain the immutable characteristics of an object, and create new objects as long as they involve modifications. These operations are done by the add () and multiply () methods. The gay class is called mutable, and it also contains the add () and multiply () methods. However, these methods can modify the Mutable object instead of creating a new one. In addition, a mutable method can produce a Immutable2 object from its data, and vice versa.
Two static methods Modify1 () and Modify2 () reveal two different methods for obtaining the same result. In Modify1 (), all work is done in the Immutable2 class, and we can see that four new Immutable2 objects were created in the process (and the first object becomes garbage each time the Val is reassigned).
In Method Modify2 (), you can see that its first action is to get Immutable2 y and then generate a mutable from it (similar to the previous call to Clone (), but this time a different type of object was created). Then, you use a mutable object to do a lot of modification without creating a new number of objects. Finally, it switches back to Immutable2. Here, we created only two new objects (mutable and Immutable2 results) instead of four.
This approach is particularly suitable for applications in the following situations:
(1) Need immutable objects, and
(2) A large number of modifications are often required, or
(3) Creating a new invariant object is too expensive