Stream
和BaseStream
中的每个方法都整齐地指定操作是中间还是(短路)终端。
例外的是close()
方法,它只声明调用关闭处理程序。
我假设close()
是一个终端操作,并且调用其他方法将导致IllegalStateException
。然而,就目前情况来看,这似乎取决于执行情况。
Javadoc中的这一遗漏是疏忽还是故意的,我是不是遗漏了什么?
Stream.close()
既不是中间操作,也不是终端操作。它实际上根本不是一个操作(在Stream API的意义上)。回想一下,在调用一个终端操作之后,不允许在同一个流上调用另一个操作。
然而,在终端操作之后,在Stream
上调用close()
不仅是允许的,而且是预期的使用,因此它不是那种流操作。关闭流的操作与禁止对流进行后续操作的终端操作具有相同的属性(以防由于已开始的终端操作而尚未禁止后续操作),这一点无可否认有点不明确。
但另一方面,这是close
操作的正常行为,即使资源或对象不可用于后续操作,因此这也适用于Streams也不应令人惊讶。
在实践中,众所周知的错误消息不言自明,因为它将"已对进行操作"或"closed"命名为拒绝后续操作的两个相同原因。
我认为Stream.close()
可以被视为终端操作流管道中的一种操作,它将流作为输入并产生结果或副作用。在执行终端操作之后,流管道被认为已被消耗,并且不能再使用
现在,如果您检查close()操作的实现,则如下所示:
public void close() {
linkedOrConsumed = true; // it sets the flag consumed as true
现在,如果你试图访问流,比如说使用映射操作,你会得到一个IllegalStateException,因为在ReferencePipelines的构建过程中有检查。
if (previousStage.linkedOrConsumed)
throw new IllegalStateException(MSG_STREAM_LINKED);
尝试使用以下代码:
Stream<String> stream = Arrays.stream(myStringNumbers);
stream.close();
List<Integer> list1 = stream.map(Integer::parseInt).collect(toList());
上面的代码将抛出IllegalStateException
。