指针是否在局部声明的末尾关闭?

Are the pointers closed at the end of the local declaration?

我有一个函数,在本地我有一些文件处理、读取 zip 文件(使用 java.util.zip.ZipFile)、流等的指针。我必须将所有这些工作包含在 try{...}catch(...){...} 语句中,但是当失败时,我必须根据错误类型一一关闭所有打开的指针。我可以通过 return?

简单地终止函数来避免这种情况吗

指针在函数内局部声明,所以我认为它们应该像任何声明的变量一样在函数结束时销毁,但作为指针,它们使用保留内存 space,所以我不'知道函数末尾的那个指针在不关闭的情况下会发生什么,不知道是销毁了,关闭了还是留在线程内无法访问的内存中。

我已经搜索过信息,但没有太大收获。有人对这个话题了解更多吗?

Are the pointers closed at the end of the local declaration?

术语:Java 没有指针。它们被称为 references.

简答:否

I must enclose all this work in a try{...}catch(...){...} statement, but when this fails I must close all the open pointers one by one according to the type of error.

部分正确。您不应关闭 catch 块中的资源。有一个更好的办法。事实上,有两种方法可以使用 try 来实现您想要做的事情。

在 Java 7 之前,您会这样做:

SomeHandle h;
try {
    h = /* open it */
    ...
} catch (...) {
    ...
} finally {
    // close the resources
    if (h != null) {
       h.close();
    }
}

从 Java 7 开始,您可以使用 try with resources 语法更简单地编写此代码:

try (Handle h = /* open it */)   // <<-- resource declarations
{
    ...
} catch (...) {
    ...
}

资源按照声明的相反顺序自动关闭。 try-with-resources 还处理关闭时抛出的异常……但我偏离了轨道。 (阅读有关 尝试使用资源 的教程以了解所有详细信息。)

Can I avoid this by simply terminating the function through a return?

没有。可关闭资源不能简单地通过 return.

关闭

The pointers are declared locally within the function, so I think they should be destroyed at the end of the function like any declared variable but being pointers they make use of reserved memory space, ...

这在很多方面都是不正确的:

  • 它们是引用而不是指针。
  • 声明的是变量,而不是引用。引用由 new 表达式创建
  • 引用指向堆中的强类型对象。 (不是 "memory space"。Java 没有办法直接引用内存。)
  • 变量不在 "destroyed" Java 中。当它们超出范围时,它们就不再是可访问的。 (这不是 "just semantics"。重点是,当变量超出范围时,绝对不会执行 "destruction" 代码。甚至不会将 null 赋值给变量。)

简而言之,您认为 Java 局部变量发生的情况实际上并没有发生。 Java 在这方面与 C++ 根本不同。

... so I don't know what happens with that pointer at the end of the function without closing it, I do not know if it is destroyed, closed or remains in memory inaccessible within the thread.

事实上,当保存引用的变量超出范围时,堆对象不会发生任何事情。

堆对象会保留在那里,直到垃圾收集器(最终!)发现该对象不再可达。然后(并且只有那时)它会删除该对象。

对于大多数对象来说,这不是问题。

对于持有需要释放的外部资源句柄的对象(例如文件描述符、内存映射文件等),这是一个问题。这就是为什么需要更直接地管理这些类型的对象的原因......通过显式关闭调用,或使用 try with resources.

(请注意,持有外部资源句柄的对象通常会有某种关闭资源的终结机制。问题是它直到垃圾回收后才会发生......这可能是太晚了。)