好记性不如铅笔头

effective java, java, 编程

《Effective Java》读书笔记:保护性拷贝

最近在看《 Effective Java 》这本书,里面提到了编码时需要注意【 保护性拷贝(Rule39) 】,这里备份下实现的注意点,截图版权属于原作者。

github:

https://github.com/cstriker1407/think_in_java 】

首先列出基本类:

class Rule39Bean
{
    public int value;
    public Rule39Bean(int value)
    {
        this.value = value;
    }
    public Rule39Bean(Rule39Bean bean)
    {
        this.value = bean.value;
    }
}
 
abstract class Period
{
    public Period(Rule39Bean small, Rule39Bean big)
    {
    }
    protected Rule39Bean small;
    protected Rule39Bean big;
    public void check()
    {
        if (small.value < big.value)
        {
            System.out.println("Right!! small < big");
        }else
        {
            System.out.println("Wrong!! small >= big");
        }
    }
    public Rule39Bean getBig()
    {
        return big;
    }
}

 使用方式A,有缺陷,未加任何保护:

class PeriodA extends Period
{
    public PeriodA(Rule39Bean small, Rule39Bean big)
    {
        super(small, big);
        this.small = small;
        this.big = big;
        if (small.value >= big.value)
        {
            throw new IllegalArgumentException("small >= big");
        }
    }
}

 测试代码:

{
    Rule39Bean small = new Rule39Bean(10);
    Rule39Bean big = new Rule39Bean(20);
    PeriodA periodA = new PeriodA(small, big);
    periodA.check();
    big.value = 5;//修改成功
    periodA.check();
}

 使用方式B,有缺陷,保护了构造函数,但是没有保护获取方法:

class PeriodB extends Period
{
    public PeriodB(Rule39Bean small, Rule39Bean big)
    {
        super(small, big);
        this.small = new Rule39Bean(small);
        this.big = new Rule39Bean(big);
        if (small.value >= big.value)
        {
            throw new IllegalArgumentException("small >= big");
        }
    }
}

 测试代码:

{
    Rule39Bean small = new Rule39Bean(10);
    Rule39Bean big = new Rule39Bean(20);
    PeriodB periodB = new PeriodB(small, big);
    periodB.check();
    big.value = 5;//修改失败
    periodB.check();
    periodB.getBig().value = 5;//修改成功
    periodB.check();
}

 使用方式C,在B的基础上增加了对获取方式的保护: 

class PeriodC extends PeriodB
{
    public PeriodC(Rule39Bean small, Rule39Bean big)
    {
        super(small, big);
    }
 
    @Override
    public Rule39Bean getBig()
    {
        return new Rule39Bean(big);
    }
}

 测试代码:

{
    Rule39Bean small = new Rule39Bean(10);
    Rule39Bean big = new Rule39Bean(20);
    PeriodC periodC = new PeriodC(small, big);
    periodC.check();
    big.value = 5;//修改失败
    periodC.check();
    periodC.getBig().value = 5;//修改失败
    periodC.check();
}

原书介绍:

发表评论

15 + 3 =

此站点使用 Akismet 来减少垃圾评论。了解我们如何处理您的评论数据