有效的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();
    }

    ...
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top