gpt4 book ai didi

java - 断言空检查

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:21:57 26 4
gpt4 key购买 nike

断言语句应该保留用于测试并在生产中禁用,这似乎已被广泛接受,因为到那时错误应该已经解决,并且启用断言会影响性能。然而,对于带有 if 语句的空检查来说,肯定也是如此。为什么这段代码被认为适合生产

if(x != null) {
x.setId(idx);
if (y != null) {
if (y.id == x.id) {
x.doSth();
}
} else {
//handle error
}
} else {
//handle error
}

但这段代码不是? (假设启用断言)

try {
assert(x != null);
x.setId(idx);
assert(y != null);
if (y.id == x.id) {
x.doSth();
}
} catch (AssertionError e) {
//handle error
}

我理解在预期变量可能不会被初始化时使用 if 语句。然而,当它用于防御性编码时,assert 似乎更加优雅和可读。

我还用这个测试了每种方法的性能:

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");
}
}

两种方法的时间大致相同:

Duration with if : 1234ms
Duration with assert : 1313ms

禁用断言几乎没有什么区别:

Duration with if : 1391ms
Duration with assert : 1375ms

我是否遗漏了任何令人信服的理由,为什么使用 if 条件进行空检查比断言更可取?

最佳答案

问问自己如何处理null 情况?如果对象为不应该的 null,您会怎么做。在大多数情况下,完全不处理它是绝对可以的。让它在稍后的执行过程中产生一个 NullPointerException。无论如何,这很可能是一个编程错误,所以被 ExceptionHandler 捕获并最终将其写入日志是可以的。

当然,有些情况下您需要对 null 对象使用react。 if-else 就是为这种情况而设计的。它很简单,不言自明,每个程序员都知道这个结构,所以为什么不使用它。无论如何,不​​鼓励在生产中使用 assert。参见 this post例如,在 SO 上。而且,就我的口味而言,使用 try/catch block 非常麻烦。

还有其他选择。例如,DavidW 建议使用注释,这非常好,只要您确保解释这些注释(例如,在迁移代码时可能会出现问题)。

另一种方法是 validator 类。例如,Apache Commons 库有一个 Validate 类,用于检查某些条件,如果条件不满足,则会抛出适当的异常。当然,您也可以编写自己的 Validators 来抛出自定义异常。你最终会得到一个简短的单行代码,比如

Validate.notNull(myObj) 
Validate.hasEmailCorrectSyntax("foo@bar.com");

另请查看 Java 的 Object.requireNotNull

关于java - 断言空检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50613910/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com