理解 UnsupportedOperationException

5
我不太了解在哪可以抛出这个异常。
例如,我正在实现Future<T>接口,不希望任何人调用方法: Future#get(long, TimeUnit).
那么,我能否只是抛出UnsupportedOperationException
public T get(long timeout, TimeUnit unit){
    throw new UnsupportedOperationException();
}

事实上,该方法的规范没有提到抛出异常。而异常则会通过"throws"关键字表明请求的操作不受支持。具体可以参考UnsupportedOperationException类。我的意思是,如果你不希望该方法被调用,抛出该异常是否常见或者是否被认为是不正确的呢?在我这个特定的案例中,我认为调用该方法没有意义...

1
是的,你的例子是使用“UnsupportedOperationException”的典型场景。 - Jan
重点是让调用者知道该操作不受支持。 - fantaghirocco
这个SO问题有一个抛出异常的例子,我认为这取决于你自己的判断。我只是想确保包含一些关于为什么会抛出异常的文档。 - Jonny Henly
@Jan 不错,但我在JavaDocs中看到(不记得具体在哪里了),有些操作(方法)不需要被实现。我认为这是唯一的情况,我们可以将其抛出。 - St.Antario
1
请看JDK中的AbstractList作为示例。 - Tunaki
为什么你觉得调用这个方法没有意义呢? - Radiodef
3个回答

10

UnsupportedOperationException技术上是未经检查的异常,因此可以在任何地方抛出。但是,在意想不到的地方抛出它将使您的类难以使用,并且并不推荐这样做。

期望抛出UnsupportedOperationException的地方是“可选操作”。Java框架包含大量此类操作,尤其是在集合框架中。例如,“add”是一项可选操作,因为不可变集合不应允许它。如果您不想编写其中一个方法,则应该抛出UnsupportedOperationException

在您的情况下,“get”定时操作对于使用Future非常重要,如果您不实现它,可能会引起某些意外。如果您打算这样做,请确保有很好的文档记录,并注意这将导致无法在某些情况下使用Future的实现,并有可能导致使用它的程序崩溃。

如果您没有资源来编写Future实现的定时get,请考虑使用已存在的实现,例如从FutureTask扩展您的类。


嗨@DJClayworth,UnsupportedOperationException违反了里氏替换原则吗? - Arash

8

是的,你说得对。

UnsupportedException 的作者是 Joshua Bloch,根据他的书和集合设计FAQ,如果对象不支持操作,则该方法可能抛出 UnsupportedException 异常。

在方法中抛出此异常时应该格外小心,因为它是 RuntimeException / 非检查异常类型。

书籍链接

书籍和 UnsupportedException 类的作者:Joshua Bloch

/**
 * Thrown to indicate that the requested operation is not supported.<p>
 *
 * This class is a member of the
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 * Java Collections Framework</a>.
 *
 * @author  Josh Bloch
 * @version %I%, %G%
 * @since   1.2
 */
public class UnsupportedOperationException extends RuntimeException {
     ...
}

让我问你一些问题。这是来自《Effective Java》吗?如果是,你引用了哪个部分? - St.Antario
是的。这段内容来自《Effective Java》一书,是关于如何使用Java语言的最佳书籍,就像好的部分一样。它来自第9章异常。 - rajuGT

4
当您希望方法的调用者知道该操作不受支持时,可以抛出UnsupportedOperationException异常。
您可以在这里进行检查:
该异常扩展了RuntimeException类,因此属于可以在Java虚拟机(JVM)运行期间抛出的异常之一。它是一个未经检查的异常,因此不需要在方法或构造函数的throws子句中声明。此外,UnsupportedOperationException自Java 1.2版本以来就存在。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接