使用什么异常来防止方法被多次调用?

What exception to use to prevent a method from being called multiple times?

我有一个方法,在对象的生命周期内只应调用一次。为了确保是这种情况,该方法将对象中的布尔标志设置为 true,以便稍后检查此方法是否已经 运行。如果在单个对象的生命周期中第二次调用此方法,我目前会抛出 IllegalArgumentException(带有描述性消息),但这对我来说感觉不太对,因为问题实际上不在于参数他们自己。有没有比 IllegalArgumentException 更好的例外?

本例中我选择不使用assert语句,因为class和方法在包外都是可见的,所以问题可能是我包外的代码引起的。这是正确的想法吗?

除了特定的异常类型之外,您更应该担心的是您在这里创建了一个糟糕的设计。

良好的界面使做正确的事变得容易,做错的事却很难。

意思是:您当前的实现可以很容易地调用该方法两次;您现在分别强制您的客户始终检查该方法是否已被调用。

因此,与其将时间花在异常类型上:退一步想想如何将一个 class 分解为 两个 classes例子。并找到一个很好的方法,以便调用该特定方法可以为您提供一个不同的对象来处理。或者检查您是否应该使用状态机来解决这个问题。

抛出一个 IllegalStateException.

但由于异常不应该是普通控制流的一部分,您应该添加一个伴随方法,returns一个布尔值,指示下一次调用该方法是否会成功。

这种伴随方法的示例是 Iterator#hasNext()

A well-designed API must not force its clients to use exceptions for ordinary control flow. A class with a “state-dependent” method that can be invoked only under certain unpredictable conditions should generally have a separate “state-testing” method indicating whether it is appropriate to invoke the state-dependent method. For example, the Iterator interface has the state-dependent method next and the corresponding state-testing method hasNext.1

1:来自 Effective Java,第 9 章:异常