什么是优选的抛出的在使用私人实用程序类的构造?
-
29-08-2019 - |
题
有效的Java(第二版), 项目4,讨论了使用私人的构造,以强制执行noninstantiability.这里的代码样本书:
public final class UtilityClass {
private UtilityClass() {
throw new AssertionError();
}
}
但是, AssertionError
看起来不像正确的事情扔。没有什么正在"断言",这是如何的API定义的使用 AssertionError.
是有一个不同的 Throwable
通常在这种情况?没有一个通常只是把一个一般 Exception
有消息吗?或者是共同编写一个自定义 Exception
为了这个?
这是很微不足道,但比什么我猜我只是好奇它从一个风格和标准的视角。
解决方案
有一种断言:"我主张,这个构造将永远不会被称为".因此,事实上, AssertionError
是正确的,在这里。
其他提示
我喜欢包括布洛克的评论:
// Suppress default constructor for noninstantiability
或者更好的是将它放在错误:
private UtilityClass()
{
throw new AssertionError("Suppress default constructor for noninstantiability");
}
UnsupportedOperationException 听起来像是最适合的,虽然经过检查的异常甚至会更好,因为它可能会警告说有人错误地实例类在编制时间。
怎么样 IllegalAcessError ? :)
不,不,没有,与所有尊重乔什-Bloch, 不要扔一个 AssertionError
除非它是从一个断言。 如果你想要一个AssertionError来,扔它 assert(false)
.然后有人阅读的代码可以找到它。
更好的是,定义自己的例外,说的 CantInstantiateUtilityClass
.然后你就会有的代码说
try {
// some stuff
} catch (CantInstantiateUtilityClass e) {
// react
}
这样读者的接球手知道 什么样的 事情发生了。
更新
每隔一些该死的傻瓜徘徊在这里和反对票持平这一次,几乎四年之后的事实。因此,我只想指出,标准 仍然 定义 AssertionError
作为结果一个失败的断言,都不如什么一些初学者认为 应该 被扔在地的定义的内容丰富的例外。可悲的是,良好的例外的学科也许是最不鼓励技术人员Java编程。
当代码需要列入JUnit作为一个依赖诸如在家试验范围 <scope>test</scope>
, 然后直接去 Assertion.fail()
方法并从中获益显着改善的清晰度。
public final class UtilityClass {
private UtilityClass() {
fail("The UtilityClass methods should be accessed statically");
}
}
当外面测试范围,可以使用类似于以下,这将需要一个静止进口使用以上。 import static pkg.Error.fail;
public class Error {
private static final Logger LOG = LoggerFactory.getLogger(Error.class);
public static void fail(final String message) {
LOG.error(message);
throw new AssertionError(message);
// or use your preferred exception
// e.g InstantiationException
}
}
其下面的使用情况。
public class UtilityClassTwo {
private UtilityClassTwo() {
Error.fail("The UtilityClass methods should be accessed statically");
}
}
在大多数习惯用的形式,他们都可以归结为:
public class UtilityClassThree {
private UtilityClassThree() {
assert false : "The UtilityClass methods should be accessed statically";
}
}
一个建立在例外情况,UnsupportedOperationException可以被扔到 表示'所要求的操作不被支持的'.
private Constructor() {
throw new UnsupportedOperationException(
"Do not instantiate this class, use statically.");
}
一个破碎的说法意味着你已经违反一项合同说明书的代码。所以这是正确的事情这里。
然而,正如我假设你会私人实例的实例,它也将呼叫的构造,并造成错误的-除非你有一个构造?
你可以创建自己的类延伸 Throwable
, ,例如:
class NoninstantiabilityError extends Throwable
这具有以下优点:
- 其名称所表明的问题
- 因为它直接延伸
Throwable
这是不可能的,它将抓住了事故 - 因为它直接延伸
Throwable
这是检查和调各自的构造事会需要赶上的例外
使用的例子:
public final class UtilityClass {
private UtilityClass() throws NoninstantiabilityError {
throw new NoninstantiabilityError();
}
...
}