2014-07-21 16 views
41

在“Effective Java,2nd edition”一书的第2部分,有这段代码,其中作者想要禁止对象的空初始化。什么是AssertionError?在哪种情况下,我应该从自己的代码中抛出它?

class Example { 
    private Example() { 
     throw new AssertionError(); 
    } 
} 

抛出异常的类型是什么让我困惑在这里。

我不明白AssertionError是否因为缺少更适合的错误或因为它应该是这样。

据我所知,当assert语句失败时,框架抛出此错误。另外,在javadoc中,它只是写成

[An AssertionError is]指出断言失败。

但是我没有看到在这里违反了任何断言(真假表)。 当然,“你不应该实例化这个类的一个项目”声明已被违反,但如果这是背后的逻辑,那么我们应该全都扔掉AssertionError,这显然不是什么情况。

FWIW,我刚抛出

new IllegalStateException("Must not instantiate an element of this class") 

。有什么不好呢?在这种情况下,我应该在自己的代码中抛出一个AssertionError

对不起,如果这只是一个微妙的疑问,但我在我的代码中使用这种模式很多,我想确保我做的是正确的事情。

+2

“断言”不仅仅意味着“断言陈述”。 – immibis

+0

番石榴有一个[有用的参考](https://github.com/google/guava/wiki/ConditionalFailuresExplained)比较了几种不同的运行时异常用例和'AssertionError'。我鼓励任何对此模式感到惊讶的人阅读本页面。 – dimo414

回答

29

当然的“不可实例化这个类的一个项目”的声明受到了侵犯,但如果这是背后的逻辑,那么我们都应该抛出AssertionErrors无处不在,这显然不会发生什么变化。

该代码并不是说用户不应该调用零参数的构造函数。有人断言说,就程序员所知,他/她已经使不可能的调用零参数构造函数(在这种情况下,通过使它为private而不是从Example的代码中调用它) 。所以如果发生呼叫,该断言已被违反,所以AssertionError是合适的。

+3

这是有道理的。所以抛出这个异常就像创建一个断言并且一次给它赋值'假',你同意吗? – doplumi

+0

@ domenicop:你明白了。 – Oliver

+0

@ domenicop:是的。 :-) –

20

AssertionError的含义是开发人员认为不可能发生的事情。

因此,如果一个AssertionError被抛出,这是一个编程错误的明显迹象。

10

一个断言当说“你写了一个代码不应该不惜代价地执行的代码,因为根据你的逻辑它不应该发生,但是如果它发生然后抛出AssertionError,你不抓住它。 “在这种情况下,你会抛出Assertion错误。

new IllegalStateException("Must not instantiate an element of this class")' // Is an Exception not error. 

注:断言错误自带java.lang.Error的下的,并不意味着错误被抓获。

+0

谢谢,我实际上把RuntimeException与一个错误混淆在一起,尽管我不知道它的差异只是在“它们不是为了被捕获”,或者“如果你捕获它们,编译器会拒绝编译你的代码” – doplumi

+1

不,你可以做'catch(Throwable t){}''但这是非常糟糕的代码。 错误和Throwable不应被捕获。比方说你会得到一个'OutOfMemoryError',你想象到你已经失去了内存和你仍然在运行的应用程序。这将不会很好。你会吹掉你的电脑(开玩笑)。 – Oliver

0

AssertionError是一个未检查异常,由程序员或API开发人员明确提出,以表明assert语句失败。

assert(x>10); 

输出:

AssertionError 

如果x不大于10,那么你将获得运行时异常的AssertionError说。

相关问题