在 Java 中使用断言是一种好习惯吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4537609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:50:04  来源:igfitidea点击:

Is it good practice to use assert in Java?

javaassert

提问by oshai

I know that the keyword assertexists in java. However I don't remember seeing code that uses it. Probably I am using exceptions and logging in places where I could have used it. Is it a good practice to use the assertkeyword in java?

我知道关键字assert存在于java中。但是我不记得看到使用它的代码。可能我正在使用异常并登录我可以使用它的地方。assert在java中使用关键字是一个好习惯吗?

EDIT: I know that assertions in general is a good practice. my question is, to be more accurate, if in java the BKM of assertion is using the assertkeyword rather than using exception, logging and other techniques.

编辑:我知道一般来说断言是一种很好的做法。我的问题是,更准确地说,如果在 java 中,断言的 BKM 使用assert关键字而不是使用异常、日志记录和其他技术。

采纳答案by Ventral

The main reason assertions are not used is because they are not enabled by default. Therefore if you have a condition that is important enough to require an assertion you can't rely on assertions being enabled to get the job done.

不使用断言的主要原因是默认情况下它们未启用。因此,如果您有一个重要到需要断言的条件,您就不能依赖启用断言来完成工作。

As other answers have correctly stated they're designed for development-time testing and debugging because they cost nothing if assertions are disabled in production. I think it's better to create explicit tests in your testing framework (e.g. a unit test for edge conditions) than rely on someone enabling assertions while testing.

正如其他答案正确指出的那样,它们是为开发时测试和调试而设计的,因为如果在生产中禁用断言,它们就不会产生任何成本。我认为最好在您的测试框架中创建显式测试(例如边缘条件的单元测试),而不是依赖某人在测试时启用断言。

However a good example I've seen for using assertions is checking private method arguments. Since you control the access to those methods you can check that your own class is using the method correctly while your public methods use more reliable argument checking techniques (annotations, if statements, 3rd-party libraries, etc). That way even if assertions are disabled your method should be protected but developers looking at the source code can see the preconditions for your method and turn assertions on for an extra safety net when working on that class.

然而,我见过的使用断言的一个很好的例子是检查私有方法参数。由于您控制对这些方法的访问,您可以检查您自己的类是否正确使用了该方法,而您的公共方法使用更可靠的参数检查技术(注释、if 语句、第 3 方库等)。这样,即使断言被禁用,您的方法也应该受到保护,但查看源代码的开发人员可以看到您的方法的先决条件,并在处理该类时打开断言以获得额外的安全网。

回答by Orlando D'Free

I used assertions a lot more when I wrote in C++ than I do in Java. I don't use them as much because I don't need them as often anymore. Many of the C++ bugs I would try to catch with assertions are no longer a problem in Java.

当我用 C++ 编写时,我使用断言的次数比用 Java 多得多。我不再经常使用它们,因为我不再经常需要它们了。我试图用断言捕获的许多 C++ 错误在 Java 中不再是问题。

Having said that, assertions are very valuable, but many people don't use them much partly because they don't understand them. I've heard people complain that they throw an Error instead of an Exception. I've also heard this question: Why don't you just use an exception and handle the case instead of using an assert?

话虽如此,断言是非常有价值的,但很多人很少使用它们,部分原因是他们不理解它们。我听说有人抱怨他们抛出错误而不是异常。我也听说过这个问题:为什么不直接使用异常并处理案例而不是使用断言?

My reply to both is the same. Assertions aren't supposed to catch cases that you expect to see in a working application. The purpose of assertions are to catch bugs. You should only use them where the only way to "handle" them is to go back and fix the code. That's why they don't throw exceptions -- You don't want them to be part of your general exception handling.

我对两者的回答是一样的。断言不应该捕获您希望在工作应用程序中看到的情况。断言的目的是捕捉错误。您应该只在“处理”它们的唯一方法是返回并修复代码的情况下使用它们。这就是它们不抛出异常的原因——您不希望它们成为常规异常处理的一部分。

As for turning them on, my IDE is set to turn them on by default. So, for my internal testing, I always know they're on.

至于打开它们,我的IDE设置为默认打开它们。因此,对于我的内部测试,我总是知道它们正在运行。

Here's an example where an assert is the only thing to use: I worked on a big Swing project where the original coders didn't understand that the UI can only be updated from the event thread, which led to all sorts of bugs. So I put in this assert in a lot of places where things were behaving funny: assert EventQueue.isDispatchThread(); If this assertion got fired, we were running from the wrong thread, and the developers needed to be notified so they could move the code to the proper thread. There's no way good to handle this in a working application.

这是一个仅使用断言的示例:我参与了一个大型 Swing 项目,其中原始编码人员不明白 UI 只能从事件线程更新,这导致了各种错误。所以我把这个断言放在了很多有趣的地方: assert EventQueue.isDispatchThread(); 如果这个断言被触发,我们从错误的线程运行,需要通知开发人员,以便他们可以将代码移动到正确的线程。在工作应用程序中没有办法处理这个问题。

回答by irreputable

Yes it's weird. The feature was highly requested, yet after it's introduced into the language, practically nobody uses it.

是的,这很奇怪。该功能被强烈要求,但在将其引入语言后,几乎没有人使用它。

I sometimes use assert as a commenting tool. Instead of

我有时使用断言作为评论工具。代替

// now it should be empty

I may write

我可以写

assert size == 0;

But I don't really turned on assert, so the assertion was never tested.

但我并没有真正打开assert,所以断言从未被测试过。

It's possible that people prefer to test the code from outside, and they don't feel the need to plant many asserts in the code flow.

人们可能更喜欢从外部测试代码,并且他们觉得没有必要在代码流中植入许多断言。

回答by Aravind Yarram

Yes it is a very good practice to assert your assumptions. Read Design By Contract. assert can be used to verify pre conditions, invariants and post conditions during integration and testing phases. This helps to catch the errors while in development and testing phases. And you can safely turn it off in production to avoid performance issues.

是的,断言你的假设是一个很好的做法。阅读合同设计。assert 可用于在集成和测试阶段验证前置条件、不变量和后置条件。这有助于在开发和测试阶段捕获错误。您可以在生产中安全地关闭它以避免性能问题。

assert's are normally used to check the correctness of your internal method logic or enforcing the contract within a given class. But use exceptions to make the contract explicit.

断言通常用于检查内部方法逻辑的正确性或在给定类中强制执行契约。但是使用异常使合同明确。

回答by darioo

Assert isn't used very much these days. It can be useful in performance critical applications during development to weed out all the bugs and then simply disabling assertions via switches.

这些天断言不常用。在开发过程中清除所有错误然后简单地通过开关禁用断言在开发过程中对性能关键的应用程序很有用。

Disabling assertions at runtime is the primary benefit, since, when disabled, they use up basically zero resources.

在运行时禁用断言是主要的好处,因为当禁用时,它们消耗的资源基本上为零。

A more "modern" approach is, for example, using Google Guava with Preconditions. This is a library type assertion mechanism that you can use when conditions must be met and you don't want to fumble around with java switches.

例如,更“现代”的方法是使用带有Preconditions 的Google Guava 。这是一种库类型断言机制,您可以在必须满足条件并且不想在 java 开关上摸索时使用它。

回答by Dhruv Gairola

in my algortihms lectures, my lecturer always maintained the usefulness of assertions. theyre mostly used for test and debugging purposes, which my be why u do see code using it. but yes, theyre highly recomended. they can be disabled if you're worried abt performance. normally i use System.out.println or breakpoints to test, but assertions are one way too. here's what i mean:

在我的算法讲座中,我的讲师始终坚持断言的有用性。他们主要用于测试和调试目的,这就是为什么你确实看到使用它的代码。但是,是的,他们强烈推荐。如果您担心性能,它们可以被禁用。通常我使用 System.out.println 或断点来测试,但断言也是一种方式。这就是我的意思:

For example, to prove that sort+reverse is equivalent to sort in reverse order:
Method 1: sort(int[] arr, int len)
// pre: len is the length of the array arr
// post: arr is sorted in ascending order
Method 2: reverse(int[] arr)
// post: the order of elements in arr is
// reversed (e.g. [9 5 10] -> [10 5 9])
Assertion 1: the length of arr is len
sort(arr,len);
Assertion 2: arr is sorted in ascending order
reverse(arr);
Assertion 3: the order of arr is reversed

回答by Famver Tags

Well, it really depends on how you look at it, but, it is recommended.

好吧,这实际上取决于您如何看待它,但是,建议这样做。

For example, if you write a method that calculates the speed of a particle, you might assert that the calculated speed is less than the speed of light.

例如,如果您编写一个计算粒子速度的方法,您可能会断言计算出的速度小于光速。

回答by Iliya Kuznetsov

I was very pleased when used assertions in my java application and sqlite-jdbc returned some smart assertion for one case.

我很高兴在我的 java 应用程序中使用断言,并且 sqlite-jdbc 为一个案例返回了一些智能断言。

So if you turn on assertions, they could appear in some third-party library.

因此,如果您打开断言,它们可能会出现在某些第三方库中。

回答by Arno Unkrig

The main reason assertions are not used is because they are not enabled by default. Therefore if you have a condition that is important enough to require an assertion you can't rely on assertions being enabled to get the job done.

不使用断言的主要原因是默认情况下它们未启用。因此,如果您有一个重要到需要断言的条件,您就不能依赖启用断言来完成工作。

I agree that the big design mistake of assertions is that they are disabled by default.

我同意断言的最大设计错误是它们默认被禁用。

Therefore I put

因此我把

static { AssertionUtil.enableAssertionsForThisClass(); }

at the top of every class. See http://commons.unkrig.de.

在每个班级的顶部。参见http://commons.unkrig.de

回答by Bozho

Yes. It is a way to validate that some "must" conditions are met. Note that you have to explicitly enable assertions.

是的。这是一种验证是否满足某些“必须”条件的方法。请注意,您必须显式启用断言。

Otherwise you can use Validatefrom commons-lang. You just write Validate.notNull(foo)and it throws an exception if foois null.

否则,您可以使用Validate来自 commons-lang。您只需编写Validate.notNull(foo),如果foo是,它就会抛出异常null