【笔记49】检查参数的有效性

绝大多数方法和构造器对于传递给他们的参数值都会有某些限制。例如索引值必须是非负数,对象引用不能为null,等等。应该在文档中清楚地指明所有这些限制,并且在方法体的开头出检查参数,以强制施加这些限制。这是“应该在发生错误之后尽快检测出错误”这一普遍原则的一个具体情形。

抛出异常

如果传递无效的参数值给方法,这个方法在执行之前先对参数进行了检查,那么它很快就会失败,并且清楚的抛出适当的异常。如果没有检查它的参数就有可能发生几种情况。该方法可能在处理过程中失败,并且产生令人费解的异常。更糟糕的是,该方法可以正常返回,但是返回的结果可能是一个错误的结果。最糟糕的情况是,该方法可以正常返回,但是却使得某个对象处于被破坏的状态,将来在某个不确定的时候,在某个不相关的点上会引发错误。

对于公有的方法,要用Javadoc的@throws标签 在文档中说明违反参数值限制时会抛出的异常。通常这样的异常为IllegalArgumentException,IndexOutOfBoundsException。一旦在文档中说明了异常,那么强加这些类型的异常检测就会是比较容易的事情,例子如下:

    /**
     * Returns a BigInteger whose value is {@code (this mod m}).  This method
     * differs from {@code remainder} in that it always returns a
     * <i>non-negative</i> BigInteger.
     *
     * @param  m the modulus.
     * @return {@code this mod m}
     * @throws ArithmeticException {@code m} ≤ 0
     * @see    #remainder
     */
    public BigInteger mod(BigInteger m) {
        if (m.signum <= 0)
            throw new ArithmeticException("BigInteger: modulus not positive");
 
        BigInteger result = this.remainder(m);
        return (result.signum >= 0 ? result : result.add(m));
    }

断言

对于未被导出的方法,也就是该方法不会被客户端代码调用的方法,作为包的创建者,你可以控制这个方法将在哪些情况下被调用,因此你可以确保只将有效的参数值传递进来。因此非公有的方法应该使用断言(Assertion)来检查参数。具体做法如下

private static void sort(long a[], int offset, int length) {
	assert a != null;
	assert offset >= 0 && offset <= a.length;
	assert length >= 0 && length <= a.length - offset;
}

断言假设 assert关键词后面的表达式为真,如果传进来的实际参数值跟我们的假设不一样,就会自动抛出AssertionError,而不需要显示手动抛出。

例外

在方法执行它的任务前,先检查它的参数。这一规则也有例外,例如在有些情况下,有效性的检查工作非常昂贵,或者根本是不切实际的,而且有效性的检查已隐含在计算过程中完成。例如,Collections.sort(list)。列表中的所有对象都是可以比较的。在排序过程中会自动检查这些参数的有效性,而并不是在构造的时候检查参数的有效性。

总结

简而言之,每当编写方法或者构造器的时候,应该考虑它的参数有哪些限制。应该把这些限制写在方法上面的注释文档中,并且考虑实施这些有效性检查的开销,权衡利弊,最后进行显示的来实施这些有效性的检查。养成这样的习惯非常重要。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值