以下是实例成员的延迟初始化的代码。这给我留下了何时执行参数验证的问题。代码中有 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) {
}
}
此代码是定制设计的,旨在提出特定疑问,因此请避免提出诸如为什么不使用构造函数传递列表?
等问题,或提出与此问题无关的代码改进建议。
最佳答案
我看不出推迟参数验证的意义,尤其是对于像检查 null
这样轻量级的事情。它有一些明显的缺点:
(正确)延迟验证会使您的代码更加复杂。
(正确)惰性验证会导致验证错误弹出,而此时却来不及采取任何措施。
话虽如此,你的例子的逻辑对我来说没有多大意义。这两个版本之间的真正区别在于,第一个版本如果不打算使用它,则根本不检查其参数。这不是“懒惰”的意思。这只是以不同的顺序做事......并因此产生不同的结果。
(就其值(value)而言,我更愿意检查 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;
}
...
}
关于java - 是否应该延迟执行参数验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21070324/