11

Autocloseable常に一緒に使用する必要がありますtry-with-resources。少なくともIntellijの検査はそれを示唆しています。したがって、Fooその実装Autocloseableを生成するコードがある場合は、次のようにする必要があります。

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

しかし、返す関数がある場合はどうなりますFoo[]か? または、引数としてFoo[](または)を受け入れる関数?Collection<Foo>

どのように使用できtry-with-resourcesますか? 次の関数を調べます。

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

やりたい事一行doAll(getFoos())

どうやってやるの?

4

3 に答える 3

7

Try-with-resources ステートメントは、ヘッダー内で宣言および割り当てられたリソースのみを閉じることができます。したがって、唯一の方法は、取得するコレクションに AutoCloseable を実装するか、それを AutoCloseable 拡張機能にラップすることです。そのため、その close() メソッドは TWR によって呼び出されます。お気に入り:

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

配列の場合、それを拡張して何らかのインターフェースを実装させることはできないため、残念ながら方法はありません。


自分でコレクションを閉じる場合は、Apache Drillプロジェクトとクラスorg.apache.drill.common.AutoCloseablesを確認してください。まさにそれを行い、多くの AutoCloseables を単独で閉じます。

于 2016-12-07T12:40:26.990 に答える
6

AutoCloseableすべての s を安全に閉じる単一の s に結合するメソッドを作成できます。

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);
}

次のような配列を返すメソッドを使用できます

Foo[] foo;
try(AutoCloseable closeAll = MyClass.closeAll(foo=getFoos())) {
    /*
        use foo
    */
}
于 2016-12-07T13:41:20.567 に答える
1

他の答えが述べているように、これは実際には不可能です。ただし、コレクション全体を AutoCloseable に入れる必要がある理由を自問する必要があります。処理後に各要素が閉じていることを確認したい場合は、次のようにすることができます。

Foo[] foos = getFoos();
for (int i = 0; i < foos.length; i++) {
  try (Foo foo = foos[i]) {
    // Your code here
  }
}
于 2016-12-07T13:02:17.393 に答える