我正在阅读优秀的清洁代码
一个讨论是关于将null传递给方法.
public class MetricsCalculator {
public double xProjection(Point p1, Point p2) {
return (p2.x - p1.x) * 1.5;
}
}
...
calculator.xProjection(null, new Point(12,13));
Run Code Online (Sandbox Code Playgroud)
它代表了处理这个问题的不同方法:
public double xProjection(Point p1, Point p2) {
if (p1 == null || p2 == null) {
throw new IllegalArgumentException("Invalid argument for xProjection");
}
return (p2.x - p1.x) * 1.5;
}
public double xProjection(Point p1, Point p2) {
assert p1 != null : "p1 should not be null";
assert p2 != null : "p2 should not be null";
return (p2.x - p1.x) * 1.5;
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢断言方法,但我不喜欢断言默认关闭的事实.
这本书最后说:
在大多数编程语言中,没有好的方法来处理由调用者意外传递的null.因为这种情况,合理的方法是禁止默认传递null.
它并没有真正涉及你如何执行这个限制?
你们中的任何一个人都有强烈的意见.
一般规则是,如果您的方法不期望null参数,那么您应该抛出System.ArgumentNullException.投掷正确Exception不仅可以保护您免受资源损坏和其他不良事件的影响,还可以为您的代码用户提供指导,从而节省调试代码所花费的时间.
另请阅读有关防御性编程的文章
使用断言和抛出异常都是有效的方法。任一机制都可用于指示编程错误,而不是运行时错误,如此处的情况。
选择实际上取决于项目的开发实践。整个项目需要决定断言策略:如果选择在所有开发过程中启用断言,那么我会说使用断言来检查这种无效参数 - 在生产系统中,由于以下原因抛出 NullPointerException无论如何,编程错误不太可能以有意义的方式被捕获和处理,因此就像断言一样。
但实际上,我知道很多开发人员不相信断言会在适当的时候启用,因此选择抛出 NullPointerException 来确保安全。
当然,如果您无法为您的代码强制执行策略(例如,如果您正在创建一个库,因此依赖于其他开发人员运行您的代码的方式),那么您应该选择抛出 NullPointerException 的安全方法。属于库 API 一部分的方法。