是否应该将 Closeable 用作 .NET 的 IDisposable 的 Java 等价物?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1165428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:28:11  来源:igfitidea点击:

Should Closeable be used as the Java equivalent for .NET's IDisposable?

javaidisposable

提问by Daniel Fortunov

Update: As @PaulGroke points out below, things have changed with Java 7: there now is AutoCloseable. Which isn't tied to streams and supported by the new try-with-resourcesconstruct.

更新:正如@PaulGroke 在下面指出的,Java 7 发生了变化:现在有了AutoCloseable。这与流无关,并由新的try-with-resources构造支持。

AutoCloseableis the direct Java equivalent for .NET's IDisposableinterface.

AutoCloseable是 .NETIDisposable接口的直接 Java 等价物。



The Closeableinterface introduced in Java 1.5 is tightly tied to streams, and even has an exception specifier for IOException. This suggests that it should only be used for streams or other IO related activities, rather than general purpose cleanup logic.

CloseableJava 1.5 中引入的接口与流紧密相关,甚至为IOException. 这表明它应该只用于流或其他与 IO 相关的活动,而不是通用的清理逻辑。

Certainly the description for the close()method would make absolutely no sense outside of a stream/IO context:

当然,该close()方法的描述在流/IO 上下文之外绝对没有意义:

void close() throws IOException

Closes this stream and releases any system resources associated with it.

void close() throws IOException

关闭此流并释放与其关联的所有系统资源。

Should I therefore declare my own interface, Disposable, with a Dispose()method on it, and use that as an analogue to .NET's IDisposableinterface? Or should I re-use Closeableeven though it may not be a perfect fit?

因此,我是否应该声明我自己的接口,Disposable并带有一个Dispose()方法,并将其用作 .NETIDisposable接口的模拟?或者我应该重新使用,Closeable即使它可能不完美?

采纳答案by Zarkonnen

Especially given that close() throws an IOException you then have to write exception handling code for, I would advise you write your own interface. This interface can then throw any checked exceptions that are appropriate to the use you want to put the interface to.

特别是考虑到 close() 抛出一个 IOException 之后,您必须为其编写异常处理代码,我建议您编写自己的接口。然后,该接口可以抛出任何适合您希望将该接口用于的用途的已检查异常。

Interfaces tend to signify intent in the mind of the reader, so having a class implement an IO-associated Closeable interface will make the reader assume the class is also IO-based.

接口往往在读者的脑海中表示意图,因此让类实现与 IO 相关的 Closeable 接口将使读者认为该类也是基于 IO 的。

Obviously, if the objects you do want to close areall IO-related, you should use Closeable. But otherwise go for

很显然,如果你的对象要关闭所有IO相关的,你应该使用可关闭。但否则去

/** Interface for objects that require cleanup post-use. Call dispose() in finally block! */
public interface Disposable {
    public void dispose();
}

回答by Paul Groke

I'm sure most people are aware of it, but since this question is still among the top results when searching for "IDisposable Java" (#2 result for me just now), and it's still not mentioned here...

我相信大多数人都知道它,但是由于在搜索“IDisposable Java”时这个问题仍然是最热门的结果(我刚才的#2结果),而且这里仍然没有提到......

Things have changed with Java 7: there now is AutoCloseable. Which isn't tied to streams and supported by the new try-with-resourcesconstruct.

Java 7 发生了变化:现在有了AutoCloseable。这与流无关,并由新的try-with-resources构造支持。

回答by TWiStErRob

When implementing Closeable(or AutoClosablefor that matter) in a class it's also possible to just omit the throws declaration:

在类中实现Closeable(或AutoClosable就此而言)时,也可以省略 throws 声明:

class X implements Closeable {
    @Override public void close() /* I don't throw */ {

    }
}

So when someone is using a typed object they can call close()without having to catch anything:

因此,当有人使用类型化对象时,他们可以调用close()而无需捕获任何内容:

void f() { // notice no need for throws because close() doesn't throw
    X x = new X();
    try {
        // do something
    } finally {
        x.close();
    }
}

It is also compatible with anything expecting a Closeable: if this object is passed into somewhere that handles Closeable, they already anticipate an exception and handle it correctly, albeit futilely in this case.

它也与任何需要 a 的东西兼容Closeable:如果这个对象被传递到某个处理 的地方Closeable,他们已经预料到一个异常并正确处理它,尽管在这种情况下是徒劳的。

This includes libraries like Guava Closeablesand Java 7 try-with-resources as Paul Groke suggests:

这包括像Paul Groke 建议的GuavaCloseables和 Java 7 try-with-resources 这样的库:

try (X x = new X()) {
    // do something
}


There's a rare caveat though: you can't reintroduce the exception in child-classes once it's stripped:

不过有一个罕见的警告:一旦它被剥离,你就不能在子类中重新引入异常:

class Y extends X {
                                  /* compile error */
    @Override public void close() throws IOException {
        // Y.close clashes with X.close: overridden method does not throw IOException
    }
}