以下是实例成员的惰性初始化代码。这让我不知道何时执行参数验证。在代码中有2个不同的函数执行NPE检查,一个延迟它,其他没有。我选择了第一个选项,但只是好奇了解行业广泛的惯例/最佳实践。
public class FreeMain {
private List<Integer> fooList;
FreeMain ( ) { }
/**
* This code does a check null pointer kind of just in time.
*
* @param barList
*/
public void putListExceptionCheckDoneLater(List<Integer> barList) {
if (this.fooList == null) {
if (barList == null) throw new NullPointerException();
this.fooList = barList;
}
}
/**
* In the even that fooList != null,
* throwing an exception would be of no benefit,
* since regardless of input, null or not, net effect would still be a no-op.
*
* @param args
*/
public void putListExceptionCheckDoneBefore(List<Integer> barList) {
if (barList == null) throw new NullPointerException();
if (this.fooList == null) {
this.fooList = barList;
}
}
public static void main(String[] args) {
}
}
此代码是专门针对特定疑问而设计的,因此请不要使用why not use constructor to pass list ?
等问题,或建议与此问题无关的代码改进。
答案 0 :(得分:3)
我看不出延迟参数验证的意义,当然对于像null
那样轻量级的东西。它有一些明确的缺点:
(True)延迟验证会使您的代码更加复杂。
(真的)延迟验证会导致验证错误弹出,因为对它们采取任何措施为时已晚。
话虽如此,你的例子的逻辑对我来说没有多大意义。两个版本之间的真正区别在于,如果它不打算使用它,第一个版本根本不会检查它的参数。这不是“懒惰”的意思。这只是以不同的顺序做事......并因此给出不同的结果。
(对于它的价值,我宁愿一直检查barList
是不是null
......假设它永远不会有意义参数为null
。这种方式可能会提前发现错误。)
对于记录,这是真正的延迟验证可能的样子:
public class LazyValidationExample {
private List<Integer> fooList;
public void putListExceptionCheckDoneLater(List<Integer> barList) {
this.fooList = barList;
}
public List<Integer> getList() {
if (this.fooList == null) throw new NullPointerException();
return this.fooList;
}
...
}