IllegalStateException 与 UnsupportedOperationException
IllegalStateException vs UnsupportedOperationException
我对使用异常感到困惑:IllegalStateException 与 UnsupportedOperationException.
我有一个在某些情况下不允许使用的删除方法:比方说当调用者拥有有效数据时。
那么我应该给用户一个异常信息,告诉他他现在正在做一个无效的操作。
那么,我应该抛出哪个异常? IllegalStateException 或 UnsupportedOperationException.
我知道我可以使用它们中的任何一个给出详细信息,但我仍然想知道哪个对我来说更好。
来自 Java文档:
- IllegalStateException:
在非法或不适当的时间调用方法的信号。换句话说,Java 环境或 Java 应用程序未处于适合请求操作的状态。
- UnsupportedOperationException:
抛出表示不支持请求的操作。
UnsupportedOperationException
应该使用,因为该方法完全不支持,而应该使用IllegalStateException
,因为该方法受支持,但在当前国家,这是不合法的。
Iterator
class 是说明这两个异常之间区别的很好的候选者。
Iterator
通过抛出 UnsupportedOperationException
:
在默认方法中实现 remove()
public interface Iterator<E> {
...
default void remove() {
throw new UnsupportedOperationException("remove");
}
...
}
不覆盖此方法来支持它的实现确实不支持该方法。
关于实现,我们可以看到 ArrayList
class 使用的 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
。
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:
此异常是为您覆盖抽象 class 或实现接口但不想或不能实现某些方法的情况而设计的。
它被 Java 集合框架的各种 class 所使用。理想情况下,您的接口或方法还应该为调用者提供一种方法,以预先确定它是否希望支持给定的操作。
我对使用异常感到困惑:IllegalStateException 与 UnsupportedOperationException.
我有一个在某些情况下不允许使用的删除方法:比方说当调用者拥有有效数据时。
那么我应该给用户一个异常信息,告诉他他现在正在做一个无效的操作。
那么,我应该抛出哪个异常? IllegalStateException 或 UnsupportedOperationException.
我知道我可以使用它们中的任何一个给出详细信息,但我仍然想知道哪个对我来说更好。
来自 Java文档:
- IllegalStateException:
在非法或不适当的时间调用方法的信号。换句话说,Java 环境或 Java 应用程序未处于适合请求操作的状态。
- UnsupportedOperationException:
抛出表示不支持请求的操作。
UnsupportedOperationException
应该使用,因为该方法完全不支持,而应该使用IllegalStateException
,因为该方法受支持,但在当前国家,这是不合法的。
Iterator
class 是说明这两个异常之间区别的很好的候选者。
Iterator
通过抛出 UnsupportedOperationException
:
remove()
public interface Iterator<E> {
...
default void remove() {
throw new UnsupportedOperationException("remove");
}
...
}
不覆盖此方法来支持它的实现确实不支持该方法。
关于实现,我们可以看到 ArrayList
class 使用的 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
。
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: 此异常是为您覆盖抽象 class 或实现接口但不想或不能实现某些方法的情况而设计的。
它被 Java 集合框架的各种 class 所使用。理想情况下,您的接口或方法还应该为调用者提供一种方法,以预先确定它是否希望支持给定的操作。