如果 JsonGenerator 是在 ByteArrayOutputStream 之上创建的,那么关闭它是否有意义

Does it make sense to close JsonGenerator if it was created on top of ByteArrayOutputStream

假设我想创建 JSON 并使用 Java JSON 流 API 将其存储在字符串中。为此,我在其上创建了 ByteArrayOutputStream (BAOS) 和 JsonGenerator。

ByteArrayOutputStream collector = new ByteArrayOutputStream();
JsonGenerator jsonGenerator = Json.createGenerator(collector);

一段时间后,当我完成它时,我从 BAOS 中获取 String 并应该释放所有资源。如下来自BAOSclose方法实现

public void close() throws IOException {
}

它什么都不做。 close JsonGenerator 的方法,然而,它不仅关闭了底层流,而且还刷新了缓冲区并回收了一个缓冲池(说实话,我不知道后者是什么意思)。
我怀疑 JsonGenerator 在将数据写入 BAOS 时会缓冲数据。但是,我需要一些时间来进一步调查它,所以我希望有人已经知道:关闭生成器是否有意义。
备注
我使用 javax.json.

的 Glassfish 实现

我认为无论底层实现如何,在完成资源时关闭资源总是有意义的。没有说未来实现不会改变,如果处理不当可能会导致资源泄漏。

如果您使用的是 Java 7 或更高版本,类 都将实现 Closeable。为什么不直接将它们放在 try-with-resources 中?

try (ByteArrayOutputStream collector = new ByteArrayOutputStream(); 
    JsonGenerator jsonGenerator = Json.createGenerator(collector)) {
    // your implementation here  
} catch (IOException e) {
    // handle exceptions
}

不需要 Java 7 之前的样板代码,您可以确保所有资源都已正确关闭。

好的。我检查了 JsonGeneratorImpl 源代码。我不得不说我真的需要关闭它。首先,JsonGeneratorImpl 在此处从 BufferPoolImpl 接收缓冲区:

public final char[] take() {
    char[] t = (char[])getQueue().poll();
    if (t == null)
        return new char[4096];
    return t;
}

当我们调用 close 时,我们把它放回去:

public final void recycle(char[] t)
{
    getQueue().offer(t);
}

如果你像我这样创建 jsonGenerator 就没有多大意义:

JsonGenerator jsonGenerator = Json.createGenerator(collector);

因为在那种情况下,每个新创建的生成器都将使用它自己的 JsonProvider 实例和它自己的缓冲池实例,当我完成使用生成器时,这些实例将由 GC 收集。所以最好创建 JsonGeneratorFactory,因为这个工厂创建的所有生成器将共享公共缓冲池。是的——在这种情况下,最后关闭生成器真的更好。
关闭生成器的另一个原因是 close 方法调用 flushBuffer 方法。是的,无论输出流类型如何,生成器都使用缓冲区:

void writeChar(char c) {
    if (this.len >= this.buf.length) {
        flushBuffer();
    }
    this.buf[(this.len++)] = c;
}

所以最后的答案是。最后关闭 JsonGenerator 总是有意义的。
更新
正如@StephenC 正确指出的那样,关闭它还有另一个原因,因为它强制检查未完成的 JSON:

if ((this.currentContext.scope != Scope.IN_NONE) || (this.currentContext.first)) {
  throw new JsonGenerationException(JsonMessages.GENERATOR_INCOMPLETE_JSON());
}