友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第164章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




是,操作非常简单:  

  

//: 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 《 10; 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);  

  }  

} ///:~  

  

注意n 在这里简化了我们的编码。  

若默认的初始化为零已经足够(便不需要构建器),而且不用考虑把它打印出来(便不需要 toString ),那 

么 IntValue 甚至还能更加简单。如下所示:  

class IntValue { int n; }  

将元素取出来,再对其进行造型,这多少显得有些笨拙,但那是Vector 的问题,不是IntValue 的错。  



12。4。1 创建只读类  



完全可以创建自己的只读类,下面是个简单的例子:  

  

//: Immutable1。java  

// Objects that cannot be modified  

// are immune to aliasing。  

  

public class Immutable1 {  

  private int data;  

  public Immutable1(int initVal) {  

    data = initVal;  

  }  

  public int read() { return data; }  



                                                                                             370 


…………………………………………………………Page 372……………………………………………………………

  public boolean nonzero() { return data != 0; }  

  public Immutable1 quadruple() {  

    return new Immutable1(data * 4);  

  }  

  static void f(Immutable1 i1) {  

    Immutable1 quad = i1。quadruple();  

    System。out。println(〃i1 = 〃 + i1。read());  

    System。out。println(〃quad = 〃 + quad。read());  

  }  

  public static void main(String'' args)  {  

    Immutable1 x = new Immutable1(47);  

    System。out。println(〃x = 〃 + x。read());  

    f(x);  

    System。out。println(〃x = 〃 + x。read());  

  }  

} ///:~  

  

所有数据都设为private,可以看到没有任何public 方法对数据作出修改。事实上,确实需要修改一个对象 

的方法是quadruple(),但它的作用是新建一个Immutable1 对象,初始对象则是原封未动的。  

方法 f()需要取得一个 Immutable1对象,并对其采取不同的操作,而 main()的输出显示出没有对x 作任何修 

改。因此,x 对象可别名处理许多次,不会造成任何伤害,因为根据 Immutable1类的设计,它能保证对象不 

被改动。  



12。4。2  “一成不变”的弊端  



从表面看,不变类的建立似乎是一个好方案。但是,一旦真的需要那种新类型的一个修改的对象,就必须辛 

苦地进行新对象的创建工作,同时还有可能涉及更频繁的垃圾收集。对有些类来说,这个问题并不是很大。 

但对其他类来说(比如 String 类),这一方案的代价显得太高了。  

为解决这个问题,我们可以创建一个“同志”类,并使其能够修改。以后只要涉及大量的修改工作,就可换 

为使用能修改的同志类。完事以后,再切换回不可变的类。  

因此,上例可改成下面这个样子:  

  

//: Immutable2。java  

// A panion 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);  

  }  

}  



                                                                                             371 


…………………………………………………………Page 373……………………………………………………………

  

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 的结果),而不是四个。  

这一方法特别适合在下述场合应用:  



                                                                                          372 


…………………………………………………………Page 374……………………………………………………………

(1) 需要不可变的对象,而且  

(2) 经常需要进行大量修改,或者  

(3) 创建新的不变对象代价太高  



12。4。3 不变字串  



请观察下述代码:  

  

//: Stringer。java  

  

public class Stringer {  

  static
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!