java Java中的IDisposable隐喻?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1768095/
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 17:52:32  来源:igfitidea点击:

IDisposable metaphor in Java?

java.net

提问by gil

As a java developer getting into .NET I'd like to understand the IDisposable interface. Could somebody please try to explain this and how it differs from what happens in Java? Thanks.

作为一名进入 .NET 的 Java 开发人员,我想了解 IDisposable 接口。有人可以尝试解释这一点以及它与 Java 中发生的情况有何不同吗?谢谢。

回答by Reed Copsey

I wrote a detailed series of articles on IDisposable.

我写了一系列关于 IDisposable详细文章

The basic idea here is that sometimes you DO need deterministic disposal of resources. IDisposable provides that mechanism.

这里的基本思想是,有时您确实需要确定性地处理资源。IDisposable 提供了这种机制。

For example, say you have a control in a Window. When this is created, it creates a windows handle (HWND) internally. When you remove the control from the Window, and its no longer used, the control becomes eligible for garbage collection - but it does not get collected right away. In fact, there are no guarantees as to how long it will be before it is collected.

例如,假设您在 Window 中有一个控件。当它被创建时,它会在内部创建一个 Windows 句柄 (HWND)。当您从 Window 中删除控件并且不再使用该控件时,该控件将有资格进行垃圾回收 - 但它不会立即被回收。事实上,无法保证在多长时间内收集。

Until the GC runs and processes the orphaned control, it will still use resources, since it's still holding the HWND.

在 GC 运行并处理孤立控件之前,它仍然会使用资源,因为它仍然持有 HWND。

IDisposable provides a means for objects that contain code that needs cleanup separate from the GC to be explicitly cleaned up by the user of the object. In the control's case, we can call myControl.Dispose(),which will immediately, synchronously cleanup the "native" resources (HWND) used by the control.

IDisposable 为包含需要与 GC 分开清理的代码的对象提供了一种方法,这些代码由对象的用户显式清理。在控件的情况下,我们可以调用myControl.Dispose(),which 将立即同步清理控件使用的“本机”资源(HWND)。

回答by Christian13467

With java 1.7 there is the new introduced try-with-resource statement.

在 java 1.7 中有新引入的 try-with-resource 语句。

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
}

The objects used here must implement AutoCloseable interface. It is not exactly the same as IDisposable, but the close()is called automatically in the finally. This gives the oportunity to implement similar behavior.

这里使用的对象必须实现 AutoCloseable 接口。它与 IDisposable 不完全相同,但close()在 finally 中会自动调用。这为实现类似行为提供了机会。

The code above is the same as

上面的代码是一样的

BufferedReader br = new BufferedReader(new FileReader(path));
try {
    return br.readLine();
} finally {
    if (br != null) br.close();
}

Read more about this in java tutorial. The samplecode is coming from there.

Java 教程中阅读有关此内容的更多信息。示例代码来自那里。

回答by elder_george

There're situations when you need reliable disposal for resources owned by your class. E.g., opened connection should be closed in proper time, not when GC decides to collect memory. In .NET method Disposeis used by convention for this. It can be called in try ... finallyblock, e.g.:

在某些情况下,您需要可靠地处理您的类拥有的资源。例如,打开的连接应该在适当的时候关闭,而不是在 GC 决定收集内存时关闭。在 .NET 中Dispose,按照惯例为此使用方法。它可以在try ... finally块中调用,例如:

IConnection conn = OpenConnection();
try{
   ...
}finally{
    conn.Dispose();
}

Because this pattern is so widely used, there's a syntactic sugar for this:

因为这种模式被广泛使用,所以有一个语法糖:

using(IConnection conn = OpenConnection()){
} // Dispose is called at the end.

As this syntax is very concise, sometimes it's useful to implement IDisposableon objects that don't own resources, but need some operation be executed at the end of its usage. E.g. consider class

由于这种语法非常简洁,有时IDisposable在不拥有资源的对象上实现很有用,但需要在使用结束时执行一些操作。例如考虑类

class TimeMeasure: IDisposable{
     public void Measure(string operation) { ... } // recourds operation time
     public void Dispose(){
        ... // print timings for all operations
     }
}

Usage:

用法:

using(TimeMeasure m = new TimeMeasure())
{
    DoFoo();
    m.Measure("Foo");
    DoBar();
    m.Measure("Bar");
} // timings for 'Foo' and 'Bar' are printed here

In Java more or less equivalent interface is Closeable. But there's no simple syntax to ensure its calls.

在 Java 中或多或少等效的接口是Closeable. 但是没有简单的语法来确保它的调用。

How IDisposableshould be implemented? This is a bit tricky:

IDisposable应该如何实施?这有点棘手:

  • if you own resources, you need to ensure they can be freed by explicit Disposecall or by GC but not by both. So, you need a flag indicating fact of disposal. For less code duplication, the disposal code is moved to separate method.
  • 如果您拥有资源,则需要确保它们可以通过显式Dispose调用或 GC释放,但不能同时由两者释放。因此,您需要一个指示处置事实的标志。为了减少代码重复,将处理代码移至单独的方法。

Example:

例子:

bool disposed;
public void Dispose(){
    Dispose(true);
    GC.SuppressFinalize(this); // tell GC not to call Finalizer() for this object
}

~MyObject(){
    Dispose(false);
}

void Dispose(bool manualDisposing){
    if(!disposed){
        disposed = true;
        if(manualDisposing)
           ... // call Dispose on all IDisposable fields
        ... // dispose all native resources
    }
}
  • if you are not holding resources, as in case of TimeMeasureclass, no need for Finalizer, you just do necessary logic in Dispose.
  • 如果您不持有资源,例如在TimeMeasure类的情况下,则不需要 Finalizer,您只需在Dispose.

回答by Yishai

Basically IDisposable at a high level, combined with the usingkeyword is giving you syntactical support for what you see as a common Java idiom like this:

基本上 IDisposable 在高层次上,结合using关键字为您提供了对您所看到的常见 Java 习语的语法支持,如下所示:

   Connection c = null;
   try {
      c = getConnection();
      ....
   } finally {
      if (c != null) {
          c.close();
      }
   }

If Java had a using keyword and an IDisposable interface with a close()method, it might look like this:

如果 Java 有一个 using 关键字和一个带有close()方法的 IDisposable 接口,它可能如下所示:

   //psudo-Java
   using(Connection c = getConnection()) {
      .....
   }

With the close method being implicitly called at the end of that block. No need for try/finally.

在该块的末尾隐式调用 close 方法。无需尝试/最终。

That being said, IDisposible has a fairly complex contract, and is mainly concerned with freeing unmanaged memory. You have to work hard with Java to have unmanaged memory (basically with JNI and Swing components, you have the concept), but it is much more common in .NET, so there is language support for the concept.

话虽如此,IDisposible 有一个相当复杂的契约,主要关注释放非托管内存。您必须努力使用 Java 才能拥有非托管内存(基本上使用 JNI 和 Swing 组件,您有这个概念),但它在 .NET 中更为常见,因此该概念有语言支持。

回答by Rajan Kumar Kharel

IDisposable interface is used to free the unmanaged resources manually.

IDisposable 接口用于手动释放非托管资源。

回答by OscarRyz

There is no equivalent.

没有等价物。

It is used when you use unmanaged resources ( in Java all the resources area managed ).

当您使用非托管资源(在 Java 中所有资源区域托管)时使用它。

In .net memory allocated by the managed resources is collected automatically by the GC ( as in Java ) .

在 .net 中,托管资源分配的内存由 GC 自动收集(如在 Java 中)。

You have additionally the opportunity to use unmanaged resources, where you will be responsible for the memory allocation and its release.

您还有机会使用非托管资源,您将负责内存分配和释放。

You call this method when you don't need the resources anymore.

当您不再需要资源时,您可以调用此方法。