Java bug与非法争论

时间:2017-02-21 04:03:18

标签: java logic assert illegalargumentexception

真的,我不太了解Java中的错误。

我已经读过您应该使用assert仅在私有函数中检查您的代码,但使用if语句抛出IllegalArgumentException。

我不能得到的是,为什么第一种情况是逻辑错误,但另一种情况是"外部用户没有提供正确的参数"?

我们说我有两个功能:

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

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

但是根据我所读到的内容,用户可以制作不合理的内容;该代码应该检查?

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

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';
}

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

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

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,因为我真的没有得到它。它真的让我感到烦恼,因为对我而言,如果没有先检查它是否有效,就没有任何意义。谢谢!

简而言之,问题可能是: 尽管已经知道一切都是正确的,但是多次检查所有内容的一致性是否正常是正常的,并且如果在检查非法参数以确保它是正确的之后如何通过呢?< / p>

1 个答案:

答案 0 :(得分:0)

“对我而言,如果没有先检查它是否有效,就没有任何意义。”然而它一直在发生。这就是错误发生的原因。存在最佳实践是因为它们在现实世界中工作,并且API写入锁定不变量(事情必须如此),因为这是确定事物不会破坏的唯一方法。所以“对我来说”从工程的角度来看是没用的,只有“什么是”很重要。

要回答你的问题,“一切都被不必要地重复检查?”,不。只有当有人做错了。要做得对,你只做必要的事情,而且你不需要仔细检查。

IllegalArgumentException这样的运行时异常的目的是告诉程序员(“你”不应该通过非法参数)他们搞砸了。这就是它的重点。

当你需要防止非法争论时,你把它放在那里。公共方法受到滥用;您需要预防或修复滥用行为,以免程序崩溃。

因为程序崩溃很糟糕。

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

你还会做什么?

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

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

你知道assert可以,并且你应该期望它在生产中被关闭。它实际上是一种活跃的文档形式。