[英]AutoCloseable contract: writing to resource allowed in close()?
我偶然发现了内部的以下构造:
class OurXmlWriter implements AutoCloseable {
private XMLStreamWriter streamWriter;
public OurXmlWriter(OutputStream stream) {
streamWriter = XMLOutputFactory.newInstance()
.createXMLStreamWriter(outputStream, "UTF-8");
}
@Override
public void close() {
try {
// is this allowed?
streamWriter.writeEndDocument();
} catch (XMLStreamException e) {
throw new RuntimeException();
} finally {
try {
streamWriter.close();
} catch (XMLStreamException e) {
throw new RuntimeException();
}
streamWriter = null;
}
}
}
我们遇到的问题是:
try (OurXmlWriter writer = new OurXmlWriter(new FileOutputStream("output.xml"))) {
writer.writeStartTag();
// write some data elements correctly
throw new OutOfMemoryError(); // that's not done explicitly but happens
}
这仍然调用close()
- 这样就可以了,但是会导致xml正确关闭(虽然不可靠,因为我确信它不能保证在Error
后成功)。
所以问题基本上是XML是有效的,尽管我们不喜欢它(因此在错过错误的情况下不会意外地处理输出)。 我正在思考如何最好地处理这种情况 - 从close()
删除结束标记 - 这需要大量的分析重新测试 - 或者只是不使用try-with-resource来控制它是否被调用。
但我的一般问题是:当你被告知close()
时, AutoCloseable
合约是否允许仍然写入你的资源? 我一直在阅读javadoc,但它并没有真正明确禁止它。 我错过了什么吗?
基本上Javadoc中没有任何东西表明它不会被允许,事实上它说的是
请注意,与
close
的方法java.io.Closeable
此close
不需要方法为幂等。 换句话说,不止一次调用此close
方法可能会产生一些可见的副作用,这与Closeable.close
不同,如果多次调用则需要它无效。
这允许副作用,甚至不要求该方法是幂等的。 考虑到写文档的结尾是一个相对不令人惊讶的副作用,我会说没关系。 但当然只是因为它不被禁止并不意味着它是允许的,YMMV,基于意见,咨询你的内部规则手册等。
Java Standard类库中有一些示例,其中close()
方法必须执行写操作。 一个这样的例子是DeflaterOutputStream
它的javadoc状态:
将剩余的压缩数据写入输出流并关闭基础流。
关键是压缩流的最后一位只能在您知道流被关闭时才会出现。 冲洗是不够的。
因此将它与@Kayaman结合使用,并且有明确证据表明允许流在close()
期间执行写入。
(另一个例子是BufferedOutputStream
,其中close()
在需要时执行相当于flush()
调用。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.