【问题标题】:IllegalStateException vs UnsupportedOperationExceptionIllegalStateException 与 UnsupportedOperationException
【发布时间】:2018-09-19 20:18:36
【问题描述】:

我对使用异常感到困惑:IllegalStateException vs UnsupportedOperationException

我有一个在某些情况下不允许使用的删除方法:假设调用者有有效数据时。

那么我应该给用户一个异常信息,他现在正在做一个无效的操作。

那么,我应该抛出哪个异常? IllegalStateExceptionUnsupportedOperationException

我知道我可以使用其中任何一个来提供详细信息,但我仍然想知道哪个更适合我的情况。

来自 JavaDoc:

  • IllegalStateException:

表示方法已在非法或不适当的时间被调用。换言之,Java 环境或 Java 应用程序未处于请求操作的适当状态。

  • UnsupportedOperationException:

抛出表示不支持请求的操作。

【问题讨论】:

  • 这主要是基于意见的。如果你只在某些非法状态下抛出异常,我会投票给IllegalStateException
  • @lexicore 尽管询问何时使用 X 和何时使用 Y 的问题似乎是基于意见的,但这两个例外之间有明显的区别,很容易我认为应该客观地解释一下。

标签: java illegalstateexception


【解决方案1】:

应该使用UnsupportedOperationException,因为该方法不支持根本,而应该使用IllegalStateException,因为该方法支持但在当前状态下是不合法的。

Iterator 类非常适合说明这两个异常之间的区别。

Iterator 通过抛出 UnsupportedOperationException 以默认方法实现 remove()

public interface Iterator<E> {
    ...
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    ...
}

不重写此方法以支持它的实现确实从不支持该方法。

关于实现,我们可以看到ArrayList 类使用的Iterator 实现覆盖remove() 以支持它。所以UnsupportedOperationException 不再被抛出。

另一方面,我们还可以看到,如果您调用该方法而您从未调用过next() 以使迭代器前进到下一个元素,则该方法会抛出IllegalStateException

private class Itr implements Iterator<E> {
    ...
    public void remove() {      
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    ...
    }
}

此实现非常支持该方法,但如果您在非法状态下调用它,则会抛出 IllegalStateException

【讨论】:

    【解决方案2】:

    IllegalStateException: 这个不太常见,但很有用,方法依赖于已调用的先前方法。

    例如,如果您的对象需要在其他方法之前调用它的 initialise() 方法,那么您可以在 initialise() 中设置一个标志,如果没有调用 initialise(),则抛出 IllegalStateException:

    private boolean initted;
    
    public void initialise() {
      // ...
      initted = true;
    }
    public void doSomething() {
      if (!initted)
        throw new IllegalStateException("Object not initialised");
    }
    

    UnsupportedOperationException: 此异常适用于您重写抽象类或实现接口但不想或不能实现某些方法的情况。

    Java 集合框架的各种类都使用它。理想情况下,您的接口或方法还应该为调用者提供一种方法来提前确定它是否期望给定的操作得到支持。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 2021-03-07
      • 1970-01-01
      • 2018-02-17
      • 2018-07-22
      相关资源
      最近更新 更多