Although the local copy generated by clone () can get the results we want on some specific occasions, the programmer (the author of the method) has to personally prohibit the side effects of alias handling. What if you want to make a library that has a general purpose but cannot guarantee that it will be cloned in the correct class? More likely, what happens if we want the alias to play a positive role-banning unwanted object duplication-but don't want to see the resulting side effects?
One way to do this is to create a "invariant object" that is subordinate to a read-only class. A special class can be defined so that no method can cause changes in the internal state of the object. In such a class, there is no problem with alias handling. Because we can only read the internal state, there is no side effect when multiple code reads the same object.
As a simple example of "invariant objects", the Java standard library contains the "wrapper" (wrapper) class, which can be used for all basic data types. As you may have discovered, if you want to save an int value in a set like vector (which uses only object handles), you can encapsulate this int inside the integer class of the standard library. As shown below:
: Immutableinteger.java
//The Integer class cannot be changed
import java.util.*;
public class Immutableinteger {public
static void Main (string[] args) {
vector v = new vector ();
for (int i = 0; i < i++)
v.addelement (new Integer (i));
But How do I change the int
//inside the Integer?
}
///:~
The integer class (and the basic "wrapper" class) implements "Invariance" in a simple form: they do not provide a way to modify an object.
If you do need an object that holds the basic data type and you want to modify the base data type, you must create them yourself. Fortunately, the operation is very simple:
: Mutableinteger.java
//A changeable wrapper class
import java.util.*;
Class Intvalue {
int n;
Intvalue (int x) {n = x;}
Public String toString () {return
integer.tostring (n);
}
}
public class Mutableinteger {public
static void Main (string[] args) {
vector v = new vector ();
for (int i = 0; i < i++)
v.addelement (new Intvalue (i));
System.out.println (v);
for (int i = 0; i < v.size (); i++)
((intvalue) V.elementat (i)). n++;
System.out.println (v);
}
} ///:~
Note that n simplifies our coding here.
If the default initialization of 0 is sufficient (no builder required) and you don't have to consider printing it (no ToString is required), then intvalue can even be simpler. As shown below:
class Intvalue {int n;}
It's awkward to take the element out and sculpt it, but it's a vector problem, not a intvalue fault.