java.util.Stack
的 pop
方法会在栈为空时抛出 EmptyStackException
异常。然而,java.util.Queue
的 remove
方法(类似于 Stack
类中的 pop
)却会抛出 NoSuchElementException
异常。为什么 Java 中存在这种不一致性?
java.util.Stack
的 pop
方法会在栈为空时抛出 EmptyStackException
异常。然而,java.util.Queue
的 remove
方法(类似于 Stack
类中的 pop
)却会抛出 NoSuchElementException
异常。为什么 Java 中存在这种不一致性?
Stack
类是Java 1.0时代的一个遗留类,在集合框架引入之前就存在了。它的接口必须向后兼容...这也是它设计的初衷。
相比之下,Queue
接口是在Java 1.5版本的集合框架中引入的。到那个时候,NoSuchElementException
被设计者选为表达这种错误条件的最佳方式1。
请注意,NoSuchElementException
本来可以在Stack
中使用,因为在Java 1.0中两个类都存在,但显然,设计者当时有其他想法2。
因此,这只是由于Java API的演变方式而产生的历史上的异常情况。它无法修复,因为这样做会破坏使用Stack
类的现有应用程序的二进制兼容性。
1 - 您可能不同意这一点,但您问为什么,这就是原因。
2- 或许他们只是太匆忙了,无法正确设计API。Java 1.0版发布时承受着极大的压力以满足市场需求。一些错误是不可避免的并且无法及时纠正。其他例子包括Enumeration
API、不赞成使用的Thread
方法、Hashtable
和Vector
类、StringBuffer
等等。但是一旦Java 1.1发布了,就为时已晚。
Stack类是最早存在的。在Javadoc中它说“自JDK 1以来”(since JDK 1)。它定义了自己的异常类型,因为它可以。
同时,NoSuchElementException已经存在,但Java集合框架还不存在。因此,广泛使用该异常还不太普遍。它只是“预定义异常”类型之一。
集合框架被添加到Java 1.2中,由于名称限制,它不能使用StackEmptyException
,这将使其仅限于与栈一起使用。
这时,旧的Stack类不能再修改,否则会破坏现有代码。Java多年来一直成功地保持向后兼容性,异常不一致是这种兼容性的一种体现。
要获得官方答案,您可以查看代码。它说:
@作者Jonathan Payne
如果你真的很重要,你可以直接联系他,问他是否还记得20年前他做了什么。也许他记得。:)
Queue
具有特殊方法,可以返回null
而不是抛出异常。在BlockingQueue
的情况下非常有用,它应该阻塞直到出现值,或者抛出异常。
在这种情况下,传统类 - Stack
- 是特殊的,因为当它为空时会抛出自己的异常。这里没有真正的不一致之处,只是集合正在服务于两个完全不同的目的。如果没有其他问题,这明确地通过异常不同来记录。
poll
方法吗? - Hai Hoangoffer
、poll
和 peek
。 - Makoto