CSDN博客

img yoti

编写不变类的准则

发表于2004/10/21 18:35:00  873人阅读


编写不变类很容易。如果以下几点都为真,那么类就是不变的:

  • 它的所有字段都是 final
  • 该类声明为 final
  • 不允许 this 引用在构造期间转义
  • 任何包含对可变对象(如数组、集合或类似 Date 的可变类)引用的字段:
    • 是私有的
    • 从不被返回,也不以其它方式公开给调用程序
    • 是对它们所引用对象的唯一引用
    • 构造后不会更改被引用对象的状态


Guidelines for writing immutable classes
Writing immutable classes is easy. A class will be immutable if all of the following are true:

  • All of its fields are final
  • The class is declared final
  • The this reference is not allowed to escape during construction
  • Any fields that contain references to mutable objects, such as arrays, collections, or mutable classes like Date:
    • Are private
    • Are never returned or otherwise exposed to callers
    • Are the only reference to the objects that they reference
    • Do not change the state of the referenced objects after construction



这儿是一个不变类文件示例:


public final class ImmutableArrayHolder {

    private final int[] theArray;

    // Right way to write a constructor -- copy the array
    public ImmutableArrayHolder(int[] anArray) {
        this.theArray = (int[]) anArray.clone();
    }

    // Right way to write an accessor -- don't expose the array reference

    public int getArrayLength() {
        return theArray.length;
    }

    public int getArray(int n)  {
        return theArray[n];
    }

    // Right way to write an accessor -- use clone()

    public int[] getArray() {
        return (int[]) theArray.clone();
    }   
}


下面是对它的一个测试类:
import junit.framework.*;

public class ImmutableArrayHolderTest extends TestCase {
    private ImmutableArrayHolder iah;
    private int[] array = {1, 2, 3, 4, 5};

    protected void setUp() {
        iah = new ImmutableArrayHolder(array);
    }

    public static TestSuite suite() {
        return new TestSuite(ImmutableArrayHolderTest.class);
    }

    public void testEquals() {
        array[3] = 5;
        Assert.assertEquals((iah.getArray())[3], 5);
    }

    public static void main(String[] args) {
        junit.textui.TestRunner.run(suite());
    }
}


测试结果:


junit.framework.AssertionFailedError: expected:<4> but was:<5>
 at ImmutableArrayHolderTest.testEquals(ImmutableArrayHolderTest.java:20)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at com.intellij.rt.execution.junit2.JUnitStarter.main(Unknown Source)

通过测试证明:array通过clone方法进行了深复制,这个类是一个不变类。

阅读全文
0 0

相关文章推荐

img
取 消
img