java只读类
尽量在一些特定的场所,由clone()发生的当地副本可以或许得到我们但愿的功效,但措施员(要领的作者)不得不亲自克制别名处理惩罚的副浸染。如果想建造一个库,令其具有通例用途,但却不能包管它必定能在正确的类中得以克隆,这时又该怎么办呢?更有大概的一种环境是,如果我们想让别名发挥努力的浸染——克制不须要的工具复制——但却不但愿看到由此造成的副浸染,那么又该如那里理惩罚呢?
一个步伐是建设“稳定工具”,令其从属于只读类。可界说一个非凡的类,使个中没有任何要领能造成工具内部状态的改变。在这样的一个类中,别名处理惩罚是没有问题的。因为我们只能读取内部状态,所以当多处代码都读取沟通的工具时,不会呈现任何副浸染。
作为“稳定工具”一个简朴例子,Java的尺度库包括了“封装器”(wrapper)类,可用于所有根基数据范例。各人大概已发明白这一点,假如想在一个象Vector(只回收Object句柄)这样的荟萃里生存一个int数值,可以将这个int封装到尺度库的Integer类内部。如下所示:
//: 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 < 10; i++) v.addElement(new Integer(i)); // But how do you change the int // inside the Integer? } } ///:~
Integer类(以及根基的“封装器”类)用简朴的形式实现了“稳定性”:它们没有提供可以修改工具的要领。
若确实需要一个容纳了根基数据范例的工具,并想对根基数据范例举办修改,就必需亲自建设它们。幸运的是,操纵很是简朴:
//: 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的错。