2009-07-22 19 views
17

更新:@PaulGrokeは以下の点を指摘しているため、Java 7で変更されました。現在はAutoCloseableです。ストリームに結びついておらず、新しいtry-with-resources構成でサポートされています。.NETのIDisposableのJava対応版としてCloseableを使用する必要がありますか?

AutoCloseableは、.NETのIDisposableインターフェイスの直接Javaに相当します。ジャワ1.5で導入さ


Closeableインタフェースがしっかりストリームに関連付けられ、さらにIOExceptionの例外指定子を有しています。これは、汎用のクリーンアップロジックではなく、ストリームやその他のIO関連アクティビティに対してのみ使用する必要があることを示しています。

確かclose()方法の説明は、ストリーム/ IOコンテキストの外で全く理にかなって:

void close() throws IOException

はこのストリームを解放、それに関連するすべてのシステムリソースを閉じます。

従って私はそれにDispose()方法で、私自身のインタフェース、Disposableを宣言、および.NETのIDisposableインターフェイスにアナログとしてそれを使用する必要がありますか?それとも、完璧にフィットしないかもしれませんが、Closeableを再使用する必要がありますか?

+1

@Pharapリンク先のページに記載されている「IDisposable」を実装するための2つのパターンがあります。 'Object.Finalize()'の実装は、あなたのオブジェクトがアンマネージドリソース(つまり、SafeHandleでラップされていないネイティブリソース)の割り当てを直接担当する比較的まれなシナリオでのみ必要です。 「IDisposable [...]を実装するために.NETが推奨する方法では、 'Object.Finalize()'」の使用が必要であるという記述は、完全に正しいわけではありません。 –

答えて

11

特に、close()がIOExceptionをスローした場合、例外処理コードを記述する必要があるため、独自のインターフェイスを記述することをお勧めします。このインターフェイスは、インターフェイスを配置する目的に適したチェックされた例外をスローできます。

インターフェースは読者の気持ちを表します。そのため、クラスにIO関連のCloseableインターフェースを実装すると、読者はそのクラスもIOベースであると見なされます。明らかに

、あなたがを閉じたくないオブジェクトは、すべてのIO-関連している場合は、開閉可能なを使用する必要があります。しかし、そうでない場合は、私はほとんどの人がそれを認識していると確信しているが、(今私のために#2の結果)「IDisposableをJavaの」を検索する際に、この質問は上位の結果の中で残っているので、

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

のために行くと、ここではまだ言及していません...

Java 7で変更されたこと:AutoCloseableがあります。ストリームに結びついておらず、新しいtry-with-resources構造によってサポートされています。

+0

私は、Javaが「IDisposable」と同等のものを得るのにそれほど時間がかかっていて、Javaの重大な欠陥であると考えていましたが、私はJavaの作成者が両方を許可する必要があることを賞賛していますコールスタックの上に伝播されるtry-block例外およびクリーンアップ式。私自身の好みは、 'try-with-resources'が' CleanupFailedException'でクリーンアップブロック内で発生した例外をラップすることでした( 'try'ブロックに何があったのかを示す) ... – supercat

+0

...また、クリーンアップコードが 'try'ブロックが成功したか失敗したかを知る手段を提供します(例えば、変更したコードによって例外がスローされた場合ロックが守られているものであれば、ロックはしばしば解放されず、無期限に保持されるべきではありませんが、ロックを獲得しようとする未決または将来の試みが直ちに 'badLockExitException'をスローするよう無効にする必要があります。 -resources構造体は、ロックオブジェクトがそのようなセマンティクスを自動的に実装できるようにすることができます)。 – supercat

+1

[Closeable](http://docs.oracle.com/javase/8/docs/api/java/io/Closeable.html)が[AutoCloseable]を拡張できるようにする後方互換性の理由がありますが、私は同意しがちですが、 (https://docs.oracle.com/javase/8/docs/api/java/lang/Au​​toCloseable.html)。考慮すべき点の1つは、例外が本体にスローされ、クリーンアップが例外をスローすると、バブルされた例外[getSuppressed](http://docs.oracle.com/javase/8/docs/api/java/lang/ Throwable.html#getSuppressed--)には[close()](https://docs.oracle.com/javase/8/docs/api/java/lang/Au​​toCloseable.html#close--)の例外が含まれています。 –

1

それが宣言投げるだけ省略することも可能ですクラスで(そのことについてまたはAutoClosableCloseableを実装:誰かが入力されたオブジェクトを使用している場合

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

    } 
} 

だから彼らがキャッチすることなくclose()を呼び出すことができます何でも:

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

またCloseableを期待して何と互換性があります。このオブジェクトは、彼らは、Closeableを扱うどこかに渡された場合既に例外を予期し、正しく処理していますが、この場合は無駄です。

ポールGrokeが示唆するように、これはGuava CloseablesとJava 7のtry-と資源のようなライブラリが含まれています

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

まれな注意点ががあります:あなたは一度子供のクラスで例外を再導入することはできません

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