在私有实用程序类构造函数中使用的首选 Throwable 是什么?
Effective Java(第二版),第 4 项讨论使用私有构造函数来强制不可实例化。 这是书中的代码示例:
public final class UtilityClass {
private UtilityClass() {
throw new AssertionError();
}
}
但是,AssertionError
似乎不是正确的抛出方法。 没有任何内容被“断言”,这就是 API 定义 断言错误。
在这种情况下是否有不同的 Throwable
? 人们通常会抛出一条带有消息的常规Exception
吗? 或者为此编写自定义Exception
是否很常见?
这是相当微不足道的,但最重要的是,我想我只是从风格和标准的角度对它感到好奇。
Effective Java (Second Edition), Item 4, discusses using private constructors to enforce noninstantiability. Here's the code sample from the book:
public final class UtilityClass {
private UtilityClass() {
throw new AssertionError();
}
}
However, AssertionError
doesn't seem like the right thing to throw. Nothing is being "asserted", which is how the API defines the use of AssertionError.
Is there a different Throwable
that's typically in this situation? Does one usually just throw a general Exception
with a message? Or is it common to write a custom Exception
for this?
It's pretty trivial, but more than anything I guess I'm just curious about it from a style and standards perspective.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
有一个断言:“我断言这个构造函数永远不会被调用”。 所以,事实上,
AssertionError
在这里是正确的。There is an assertion: "I'm asserting that this constructor will never be called". So, indeed,
AssertionError
is correct here.我喜欢包括布洛赫的评论:
或者更好地将其放入错误中:
I like including Bloch's comment:
Or better yet putting it in the Error:
UnsupportedOperationException 听起来是最合适的,尽管检查异常会更好,因为它可能会警告某人在编译时错误地实例化该类。
UnsupportedOperationException sounds like the best fit, though a checked exception would be even better, since it might warn someone erroneously instantiating the class at compile time.
IllegalAcessError 怎么样? :)
What about IllegalAcessError ? :)
当代码需要将 JUnit 作为依赖项包含在内(例如在 Maven 测试范围内)
test
,则直接转到Assertion.fail() 方法并受益于清晰度的显着提高。
当超出测试范围时,您可以使用类似以下内容的内容,这需要静态导入才能像上面一样使用。
import static pkg.Error.fail;
其中用法如下。
在其最惯用的形式中,它们都归结为:
内置异常之一,UnsupportedOperationException 可以被抛出到
指示“不支持请求的操作”。
When the code requires the inclusion of the JUnit as a dependency such as within the maven test scope
<scope>test</scope>
, then go straight toAssertion.fail()
method and benefit from significant improvement in clarity.When outside the test scope, you could use something like the following, which would require a static import to use like above.
import static pkg.Error.fail;
Which the following usage.
In its most idiomatic form, they all boil down to this:
One of the built in exceptions, UnsupportedOperationException can be thrown to
indicate that 'the requested operation is not supported'.
不不不,恕我直言,永远不要抛出
AssertionError
,除非它来自断言。如果您想要在这里出现 AssertionError,请使用assert 抛出它(假)
。 然后阅读代码的人可以稍后找到它。更好的是,定义您自己的异常,例如
CantInstantiateUtilityClass
。 然后你将得到这样的代码,以便捕手的读者知道发生了什么。
让我注意一下,标准仍然将
AssertionError
定义为失败断言的结果,而不是某些初学者认为应该抛出的结果明确定义的信息异常的地方。 遗憾的是,良好的异常纪律可能是 Java 编程中最不值得鼓励的技能。No no no, with all due respect to Josh Bloch, never throw an
AssertionError
unless it's from an assertion. If you want an AssertionError here, throw it withassert(false)
. Then someone reading the code can find it later.Even better, define your own exception, say
CantInstantiateUtilityClass
. then you'll have code that saysso that the reader of the catcher knows what happened.
Let me just note that the standard still defines
AssertionError
as the result of a failed assertion, not as what some beginner thinks ought to be thrown in place of a well-defined informative exception. Sadly, good exception discipline is perhaps the least encouraged skill in Java programming.断言被破坏意味着您已经破坏了代码的合同规范。 所以这是正确的事情。
但是,正如我假设您将私下实例化一个实例一样,它也会调用构造函数并导致错误 - 除非您有另一个构造函数?
A broken assertion means that you've broken a contract specification of your code. So it's the right thing here.
However, as I assume you'll be privately instantiating an instance, it will also call the constructor and cause an error- unless you have another constructor?
您可以创建自己的类来扩展
Throwable
,例如:这具有以下优点:
Throwable
,所以不太可能被捕获由于示例:
You can create your own class extending
Throwable
, e.g.:This has the following advantages:
Throwable
it is unlikely that it will be caught by accidentThrowable
it is checked and calling the respective constructor by accident would require catching the exceptionUsage example: