Java bug 与非法参数

标签 java logic assert illegalargumentexception

真的,我不太明白什么是 Java 中的错误。

我读到您应该使用 assert 仅在私有(private)函数中检查代码,但使用 if 语句抛出 IllegalArgumentException。

我不明白的是,为什么第一种情况是逻辑错误,而另一种情况是“外部用户没有提供正确的参数”?

假设我有两个函数:

public boolean isDigit(char c) { return c >= '0' && c <= '9'; }
public int toInt(char c) { return c - '0'; }

在我编写的所有代码中,在调用 toInt 之前,我会首先检查以确保它是数字,否则它没有意义!

但是根据我所读到的内容,用户可以做出没有意义的事情;代码应该检查这一点吗?

为了使代码健壮,我添加了一个断言以确保参数正确。这些只是为了在调试时检查错误......

public int toInt(char c) { assert isDigit(c); return c - '0'; }

但是我读到这不是 Java 中应该做的事情?你应该这样做:

public int toInt(char c) {
    if (!isDigit(c)) {
        throw new IllegalArgumentException("char is not a digit");
    }
    return c - '0';
}

这对我来说真的很难看,因为我应该在调用函数之前检查参数是否有效!双重检查是否以某种方式优化?

当我看到上面的代码时,在我看来,就像这样简单的代码:

char c = '0';
if (isDigit(c)) {
    int i = toInt(c);
} else {
    doSomethingElse...;
}

变成这样:

char c = '0';
if (isDigit(c)) {
    if(!isDigit(c)) {
        throw new IllegalArgumentException("char is not a digit");
    }
    int i = c - '0';
}
...

一切都经过不必要的双重检查,这正常吗?这是 Java 的做事方式吗?

如果是这样,我想知道除了逻辑错误之外还会如何发生 IllegalArgumentException,因为我真的不明白。这真的让我很烦恼,因为对我来说,在没有首先检查其有效性的情况下,有人实际上提出论点是没有意义的。谢谢!

简而言之,问题可能是: 即使已知所有内容都是正确的,但都会多次检查其一致性,这是否正常?在检查确保其正确性后,如何会传递非法参数?

最佳答案

“对我来说,在没有首先检查其有效性的情况下,有人实际上提出论点是没有意义的。”然而这种事却时常发生。 bug 就是这样发生的。最佳实践之所以存在,是因为它们在现实世界中有效,而 API 编写了锁定不变量(事情必须如此),因为这是确保某些事情不会被破坏的唯一方法。因此,从工程的角度来看,“对我来说”是没有用的,只有“是什么”才重要。

回答你的问题,“一切都不必要地经过双重检查?”,不。只有当有人做错事的时候。为了正确地做到这一点,您只做必要的事情,并且不需要双重检查。

IllegalArgumentException这样的运行时异常的目的是向程序员(“对你来说”不应该传递非法参数的人)发出信号,表明他们搞砸了。这就是重点。

当您需要防止非法争论时,您可以将其放在那里。公共(public)方法容易被滥用;您需要防止或修复滥用行为,以便您的程序不会崩溃。

因为程序崩溃很糟糕。

“我读到您应该使用断言仅在私有(private)函数中检查您的代码。”别再读那些作者的书了。您不使用 assert 来检查您的代码。您使用程序逻辑来检查您的输入和条件。 (您称之为 if。)您使用 assert 来确认不变量。例如,如果您接受一个应该是数字的char,那么您当然会检查它是否是一个数字!如果你不这样做,你的程序将会崩溃,或者更糟的是,不会崩溃但会产生不好的结果。

你还会做什么?

拒绝非数字的结果是一个不变量,即您的值是数字。在安全地通过异常抛出或提前返回后,然后断言。

if (! isDigit(c)) { throw new IllegalArgumentException("non-digit");}
assert isDigit(c);

您知道 assert 可以并且您应该预料到它会在生产中关闭。这实际上是一种 Activity 文档形式。

关于Java bug 与非法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42358452/

相关文章:

php - 如何根据用户互动/最感兴趣的用户对帖子进行排序

Javascript Material 条件

Java:从文本文件导入到 ArrayList - 越界错误

java - 创建由子类初始化的最终字段

jQuery 表单验证逻辑

python - 我可以在 AssertionError 上强制调试 python 吗?

c++ - POD 中的 static_assert 会破坏 POD 吗?

java - 同时接受多个IntellijIdea的检查建议(都是同类型)

java - 服务器/客户端不通过套接字发送或接收数据[Java]?

java - PowerMockRunner初始化错误