2016-12-07 16 views
4

Autocloseableは、常にtry-with-resourcesで使用する必要があります。少なくともIntellijの検査で示唆されています。だから、 、私は私が何をすべきAutocloseableを実装Fooを生成したコードがある場合:私はFoo[]を返す関数を持っている場合Java8の "Autocloseable"の配列またはコレクション

try (final Foo foo = getFoo()) { 
    foo.doSomething(); 
} 

しかし、何を?または、引数としてFoo[](またはCollection<Foo>)を受け入れる関数ですか?

try-with-resourcesでどうすれば使用できますか? は、以下の機能を見て:

Foo[] getFoos(); 
doAll(Foo... foo); 

私はそれをどのように行うことができますラインdoAll(getFoos())

何かをしたいですか?

答えて

4

Try-with-resourcesステートメントは、そのヘッダー内で宣言され割り当てられたリソースのみを閉じることができます。そのため、唯一の方法は、AutoCloseableを実装するCollectionを作成するか、AutoCloseable拡張にラップすることです。そのため、close()メソッドはT-W-Rによって呼び出されます。同様に:

try (SomeAutoCloseableCollction col = getAutoCloseables()) { 
     System.out.println("work"); 
} //col.close() gets called 

配列の場合、拡張することができないし、いくつかのインターフェイスを実装することはできませんので、私は恐れがあります。


自分でコレクションをクローズした場合、Apache Drillプロジェクトとクラスorg.apache.drill.common.AutoCloseablesを見てすることができる - それは、それ自体でAutoCloseablesの多くを閉じ、まさにそれを行います。

1

もう1つの答えとして、これは実際には不可能です。ただし、コレクション全体をAutoCloseableに配置する必要がある理由を自分自身で確認する必要があります。あなたが安全にそれらのすべてを閉鎖する単一のものにAutoCloseable秒を組み合わせるためのメソッドを作成することができます

Foo[] foos = getFoos(); 
for (int i = 0; i < foos.length; i++) { 
    try (Foo foo = foos[i]) { 
    // Your code here 
    } 
} 
+0

のように配列を返すメソッドを使用することはできますが、誰もが道を見ない場合は編集で私の答えを更新してください。 –

+4

あなたは 'for(Foo foo:getFoos())try(Foo toClose = foo){/ * code * /}'を意味しますか?それはうまくいくはずです。 – Holger

3

public static AutoCloseable closeBoth(AutoCloseable a, AutoCloseable b) { 
    if(a==null) return b; 
    if(b==null) return a; 
    return() -> { try(AutoCloseable first=a) { b.close(); } }; 
} 
public static AutoCloseable closeAll(AutoCloseable... c) { 
    return Arrays.stream(c).reduce(null, MyClass::closeBoth); 
} 
をあなたは必ず各要素は、処理後に閉じているようにしたい場合は、あなたのような何かを行うことができます

は、彼らは私が拡張forループでこの作品を作るための方法を見つけることができませんでし

Foo[] foo; 
try(AutoCloseable closeAll = MyClass.closeAll(foo=getFoos())) { 
    /* 
     use foo 
    */ 
}