“一成稳定”的漏洞(java)
从外貌看,稳定类的成立好像是一个好方案。可是,一旦真的需要那种新范例的一个修改的工具,就必需辛苦地举办新工具的建设事情,同时尚有大概涉及更频繁的垃圾收集。对有些类来说,这个问题并不是很大。但对其他类来说(好比String类),这一方案的价钱显得太高了。
为办理这个问题,我们可以建设一个“同志”类,并使其可以或许修改。今后只要涉及大量的修改事情,就可换为利用能修改的同志类。完事今后,再切换回不行变的类。
因此,上例可改成下面这个样子:
//: 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(12).multiply(3).add(11).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());
}
} ///:~
和往常一样,Immutable2包括的要领保存了工具不行变的特征,只要涉及修改,就建设新的工具。完成这些操纵的是add()和multiply()要领。同志类叫作Mutable,它也含有add()和multiply()要领。但这些要领可以或许修改Mutable工具,而不是新建一个。除此以外,Mutable的一个要领可用它的数据发生一个Immutable2工具,反之亦然。
两个静态要领modify1()和modify2()展现出得到同样功效的两种差异要领。在modify1()中,所有事情都是在Immutable2类中完成的,我们可看到在历程中建设了四个新的Immutable2工具(并且每次从头分派了val,前一个工具就成为垃圾)。
在要领modify2()中,可看到它的第一个动作是获取Immutable2 y,然后从中生成一个Mutable(雷同于前面临clone()的挪用,但这一次建设了一个差异范例的工具)。随后,用Mutable工具举办大量修改操纵,同时用不着新建很多工具。最后,它切换回Immutable2。在这里,我们只建设了两个新工具(Mutable和Immutable2的功效),而不是四个。
这一要领出格适合在下述场所应用:
(1) 需要不行变的工具,并且
(2) 常常需要举办大量修改,可能
(3) 建设新的稳定工具价钱太高