似乎广泛接受断言语句应保留用于测试和生产中禁用,因为错误应该已经解决,并且启用断言会影响性能.然而,使用if语句进行空检查肯定也是如此.为什么这段代码被认为适合生产
if(x != null) {
x.setId(idx);
if (y != null) {
if (y.id == x.id) {
x.doSth();
}
} else {
//handle error
}
} else {
//handle error
}
Run Code Online (Sandbox Code Playgroud)
但这段代码不是吗?(假设启用了断言)
try {
assert(x != null);
x.setId(idx);
assert(y != null);
if (y.id == x.id) {
x.doSth();
}
} catch (AssertionError e) {
//handle error
}
Run Code Online (Sandbox Code Playgroud)
我理解在预期变量可能未初始化时使用if语句.然而,当它用于防御性编码时,断言似乎更优雅和可读.
我还测试了每种方法的性能:
public class AssertTest {
static final int LOOPS = 10000000;
public static void main(String[] args) {
String testStr = "";
long startNotEqualsTest = System.currentTimeMillis();
for (int i = 0; i < LOOPS; i++) {
if (testStr != null) {
testStr = System.currentTimeMillis() + "";
} else {
throw new RuntimeException("We're doomed");
}
}
long notEqualsTestDuration = System.currentTimeMillis() - startNotEqualsTest;
testStr = "";
long startAssertTest = System.currentTimeMillis();
for (int i = 0; i < LOOPS; i++) {
try {
assert(testStr != null);
testStr = System.currentTimeMillis() + "";
} catch (AssertionError e) {
throw new RuntimeException("We're doomed");
}
}
long assertTestDuration = System.currentTimeMillis() - startAssertTest;
System.out.println("Duration with if : " + notEqualsTestDuration + "ms");
System.out.println("Duration with assert : " + assertTestDuration + "ms");
}
}
Run Code Online (Sandbox Code Playgroud)
两种方法的时间安排大致相同:
Duration with if : 1234ms
Duration with assert : 1313ms
Run Code Online (Sandbox Code Playgroud)
禁用断言几乎没有区别:
Duration with if : 1391ms
Duration with assert : 1375ms
Run Code Online (Sandbox Code Playgroud)
我是否错过了任何令人信服的理由,为什么如果条件优于断言,则进行空检查?
问问自己如何处理null案件?如果一个对象null不应该是你做什么的.在大多数情况下,完全没有处理它.让它NullPointerException在执行后的某个时间产生.无论如何,它很可能是编程错误,因此ExceptionHandler最终可以将其写入日志中.
当然,有些情况下您需要对null对象做出反应.if-else就这种情况而言.这很容易,自我解释,每个程序员都知道构造,所以为什么不使用它.assert无论如何,在生产中是沮丧的.例如,请参阅SO上的这篇文章.而且,根据我的口味,使用try/catch块非常麻烦.
还有其他选择.例如,DavidW建议使用注释,这是完全没问题的,只要您确保解释这些注释(例如,在迁移代码时可能会出现问题).
另一种方法是Validator类.例如,Apache Commons库有一个Validate类,用于检查某些条件,如果条件未满,则会抛出相应的异常.当然,您也可以编写自己的Validators来抛出自定义异常.你最终会得到一个简洁的单行内容
Validate.notNull(myObj)
Validate.hasEmailCorrectSyntax("foo@bar.com");
Run Code Online (Sandbox Code Playgroud)
另请参阅 Java的Object.requireNotNull
| 归档时间: |
|
| 查看次数: |
4109 次 |
| 最近记录: |