[Google Guava] 1.2-前置条件

原文链接 译文链接 译者: 沈义扬

前置条件:让方法调用的前置条件判断更简单。

Guava在Preconditions类中提供了若干前置条件判断的实用方法,我们强烈建议在Eclipse中静态导入这些方法。每个方法都有三个变种:

  • 没有额外参数:抛出的异常中没有错误消息;
  • 有一个Object对象作为额外参数:抛出的异常使用Object.toString() 作为错误消息;
  • 有一个String对象作为额外参数,并且有一组任意数量的附加Object对象:这个变种处理异常消息的方式有点类似printf,但考虑GWT的兼容性和效率,只支持%s指示符。例如:

[code lang=”java”]
checkArgument(i >= 0, "Argument was %s but expected nonnegative", i);
checkArgument(i < j, "Expected i < j, but %s > %s", i, j);
[/code]

方法声明(不包括额外参数) 描述 检查失败时抛出的异常
checkArgument(boolean) 检查boolean是否为true,用来检查传递给方法的参数。 IllegalArgumentException
checkNotNull(T) 检查value是否为null,该方法直接返回value,因此可以内嵌使用checkNotNull NullPointerException
checkState(boolean) 用来检查对象的某些状态。 IllegalStateException
checkElementIndex(int index, int size) 检查index作为索引值对某个列表、字符串或数组是否有效。index>=0 && index<size * IndexOutOfBoundsException
checkPositionIndex(int index, int size) 检查index作为位置值对某个列表、字符串或数组是否有效。index>=0 && index<=size * IndexOutOfBoundsException
checkPositionIndexes(int start, int end, int size) 检查[start, end]表示的位置范围对某个列表、字符串或数组是否有效* IndexOutOfBoundsException

译者注:

*索引值常用来查找列表、字符串或数组中的元素,如List.get(int), String.charAt(int)

*位置值和位置范围常用来截取列表、字符串或数组,如List.subList(int,int), String.substring(int)

相比Apache Commons提供的类似方法,我们把Guava中的Preconditions作为首选。Piotr Jagielski在他的博客中简要地列举了一些理由:

  • 在静态导入后,Guava方法非常清楚明晰。checkNotNull清楚地描述做了什么,会抛出什么异常;
  • checkNotNull直接返回检查的参数,让你可以在构造函数中保持字段的单行赋值风格:this.field = checkNotNull(field)
  • 简单的、参数可变的printf风格异常信息。鉴于这个优点,在JDK7已经引入Objects.requireNonNull的情况下,我们仍然建议你使用checkNotNull。

在编码时,如果某个值有多重的前置条件,我们建议你把它们放到不同的行,这样有助于在调试时定位。此外,把每个前置条件放到不同的行,也可以帮助你编写清晰和有用的错误消息。

原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: [Google Guava] 1.2-前置条件

  • Trackback 关闭
  • 评论 (4)
    • ransom
    • 2014/01/22 9:13下午

    可惜预判返回的一场大多都是runtimeexception的,不能自定义异常,这个挺郁闷,
    对于runtime异常,上层调用完全不知道,总不能捕获所有的exception吧。

    • Preconditions的异常类型问题 牵扯到设计准则,后面的章节‘Throwables’也提到了一点。一般准则认为,违反方法契约(包括方法所使用的对象或外部数据状态)时抛出UncheckedException,其定义方法的可用性范畴;而方法因为不可控原因无法履行契约,则抛出CheckedException。 所以Preconditions就跟它的名字一样,是用来定义方法契约的,这样方法才算完整地自描述和可重用了。
      对设计理想的应用来说,Runtimeexception应该绝少触发。当调用这些方法时,你可以根据领域对象的业务含义,在调用方预先作检查,比如bean-validator这样的手段。而详细去看bean-validator的定义时,你就会发现它完全撇清了检查和异常的概念。

    • zhangzhang
    • 2014/12/08 7:52下午

    检查参数不符合预期的情况不一定都要抛出异常啊,针对不符合预期的结果处理,不能都在catch中完成吧?

    • dream_yukun
    • 2019/09/07 11:51上午

    针对于Guava,最近才开始尝试引入! 贴合实际开发中,只用了一项 checkArgument(boolean)!
    但是无比好用,将我从原有的if else中的业务校验中解放出来!
    其他的虽然也想用,但是跟楼上的大佬一样,校验异常抛出后需要额外的处理,不处理下游就一脸懵逼…
    基于设计原则上没有问题,但是实际开发中, 我会选择最实用的

return top