EffectiveJava学习笔记21:检查参数有效性、保护性拷贝

1.检查参数有效性

这个主要是建议我们当参数有些特殊的限制时,需要检查参数的正确与否。

可被导出(public、protected)的方法

比如:限制参数不能小于0

 /** 
  * @param m the modulus,which must be positive 
  * @return this mod m 
  * @throwsArithmeticException if m is less then or equal to 0 
  */ 
  public int mod(BigInteger m){ 
      if (m.signum() <= 0 ) { 
         throw new ArithmeticException("Modulus <=0 : " + m); 
      } 
      return this.n.signum() % m.signum(); 
  } 

这个是书中的一个案例,它通过调用参数的副产物m.signum()的比较是否小于等于0,来进行抛出,并且在javadoc说明文档注释中写明了@throwsArithmeticException 抛出说明。当然这个有个缺点,就是javadoc的错误抛出只能用于public(共有)与protected(受保护的)。

比如:限制参数不能为null

这里介绍一个java7中的null检查方法:Objects.requireNonNull方法。它可以返回其输入,且同时进行null检查

this.xx=Objects.requireNonNull(xx,"xx"); 

未能被导出(private)的方法

对于非公有方法,通常使用断言(assertion)来检查参数的

private void test(int a){

  assert a!=null;

}  

2.保护性拷贝

什么是保护性拷贝?

很简单,就是将对象或引用拷贝成一个新的,然后用新的对象(引用)来进行操作,避免可变出错。

例子:

/**
 *  未进行保护性拷贝
 *  @author sardine
 * */
public class TestClass {
    private final Date Start;
    private final Date end;

    public TestClass(Date start, Date end) throws IllegalAccessException {
        if(start.compareTo(end)>0){throw new IllegalAccessException("开始时间大于结束时间");}
        this.Start = start;
        this.end = end;
    }
}

这里会导致一个问题,就是Date类本身是可变的,在判断后依然有可能造成开始时间大于结束时间;

一种解决方法是使用Instant(或LocalDateTime或ZonedDateTime)代替Date;,因为这些类是不可变的。

另一种解决方法就是使用保护性拷贝:备份对象,将其作为实例组件,而不使用原始的对象:

/**
 *  保护性拷贝
 *  @author sardine
 * */
public class TestClass {
    private final Date Start;
    private final Date end;

    public TestClass(Date start, Date end) throws IllegalAccessException {
        this.Start = new Date(start.getTime());
        this.end = new Date(end.getTime());
        if(start.compareTo(end)>0){throw new IllegalAccessException("开始时间大于结束时间");}
    }
}

这里可以发现,它不适用原始参数start,而是通过new Date(start.getTime()),进行一个保护性拷贝来进行赋值的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值