编写不变类的准则


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

  • 它的所有字段都是 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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值