1ParameterValidation的意义大多数方法都会限制传递给它们的参数值。常见的例子包括非负索引值和非空引用。作为一个优雅的开发者,你应该:将这些限制清楚地记录在JavaDoc中,并在方法体的开头进行验证,出现错误后尽快发现。如果不这样做,错误就不太可能被检测到,即使检测到,也很难确定它们的来源如果没有验证参数,则在方法执行过程中可能会出现以下情况:莫名其妙的异常导致失败并正常返回,但计算错误的结果会被偷偷正常返回,但它会将一个对象置于隐藏状态,这可能会在未来某个不确定的时间某个不相关的代码点报错。总之,如果未验证参数,则可能会违反失败原子性。对于public和protected方法,在方法描述中使用Javadoc的@throws标签来描述如果超出参数值限制将抛出的异常。通常是IllegalArgumentException、IndexOutOfBoundsException或NullPointerException。一旦记录了参数限制,并且记录了违反时将抛出的异常,施加这些限制就变得微不足道了。看看这个案例:文档注释没有说“如果m为空,mod将抛出NPE”,但是方法确实如此,就像调用m.signum()的副产品一样。该异常记录在封闭的BigInterger类级别的文档注释中。类级注释适用于该类所有公共方法中的所有参数。这避免了在每个方法上分别记录每个NullPointerException的混乱情况。可以与@Nullable或类似的注解结合使用来指示一个参数可能为空,但这不是标准的,并且使用了多个注解。2最佳实践Java7提供了Objects.requireNonNull来消除手动执行null检查的需要。如果您愿意,您还可以自定义异常详细信息。这个方法返回它的输入,所以你可以在使用一个值的同时进行空判断://Java内置的空判断函数this.strategy=Objects.requireNonNull(strategy,"strategy");也可以忽略返回值,使用Objects.requireNonNull作为判断void的独立方法。3边界检查在Java9中,边界检查功能被添加到java.util.Objects中。这个函数由三个方法组成:checkFromIndexSizecheckFromToIndexcheckIndex这套工具不如empty方法灵活。它不允许自定义异常详细信息,仅适用于列表和数组索引,并且不处理封闭范围(包含两个端点)。4Assertions对于未暴露的方法,作为封装开发者,应该控制方法什么时候可以被调用,所以可以也应该保证只传入有效的参数值。因此,非public方法可以使用断言来检查传入参数:本质上,这些断言断言断言条件为真,无论客户端如何调用它。与普通验证的区别在于:如果断言失败,将抛出AssertionError如果断言无效,则基本上没有成本,除非通过将-ea或-enableassertion标志传递给java命令来启用它们。静态工厂方法应该特别检查那些还没有被方法调用的,但是保存参数的有效性以备后用。例如,一个静态工厂方法接受一个整数数组并返回该数组的列表视图。如果客户端传入null,则会抛出NullPointerException,因为该方法有显式检查(调用Objects.requireNonNull)。如果省略检查,这将返回对新创建的List实例的引用,如果客户端尝试使用它,它将抛出NullPointerException。此时,List实例的来源很难确定,使调试变得复杂。构造函数是一个特例。一定要检查构造函数输入参数的合法性,以免在构造生成的实例对象时违反对象的不变性。例外情况在执行方法之前应明确检查参数的例外情况-有效性检查代价高昂或不切实际,或者在计算期间隐式执行检查。例如,对对象列表进行排序的方法,例如Collections.sort(List)。列表中的所有对象都必须相互比较。在对List进行排序的过程中,List中的每个对象都会与列表中的其他对象进行比较。如果对象不能相互比较,将抛出ClassCastException,这正是sort方法应该做的。因此,不需要预先检查列表的元素是否具有可比性。但是不分青红皂白地依赖隐式有效性检查会导致失败时失去原子性。有时计算任务会隐式执行所需的有效性检查,但如果检查失败则抛出异常。即计算任务因参数值无效抛出的异常与文档中记录的方法抛出的异常不匹配。这时候就应该使用异常转换,将计算任务抛出的异常转换为正确的异常。5结论不要把这篇文章认为限制参数总是一件好事。我们追求的是一种通用的、实用的方法设计。如果该方法能够相当好地处理它接受的所有参数值,那么对参数施加的限制越少越好。建议大家在每次写方法的时候都考虑参数的限制。记录这些限制并在方法主体的开头明确检查它们。养成习惯!当验证失败时,这一小部分工作会让您微笑!参考《阿里 Java 开发手册》《重构》《Effective Java》
