2

そのため、Java 7 にはクラスを自動的に閉じる気の利いた機能がありますAutoCloseableBar実装Closeable(これは を拡張します) があり、からAutoCloseableオープンを取得する方法がある場合、これを行うことができます。BarFoo

try(Bar bar=foo.openBar())
  //do something
}

...そして、句barに入れられたかのように、自動的に閉じられます。finally素晴らしい。

Barしかし、 を取得して後で開きたい場合はどうすればよいでしょうか。おそらく aBarは a に似ていてFile、単にリソースを識別するためです。それらの多くを識別したい場合がありますが、必要な場合にのみ開きます。

Bar bar=foo.getBar();
try(bar.open())  //doesn't work
  //do something
}

tryしかし、Java 7 の自動管理アプローチでは、句で変数を割り当てる必要がありますよね?

だから多分私は賢くてBar.open()リターンthis(つまりBarインスタンス)を持つことができるので、これを行うことができます:

try(Bar bar=foo.getBar().open())
  //do something
}

これは私が望むように機能しますが、中間Barインスタンスが閉じられないという警告が表示されます。

だから多分私はこれを行うことができます:

Bar bar=foo.getBar();
try(Bar temp=bar.open())
  //do something
}

これも私が望むように機能しますが、醜いだけでなく、まだ警告が表示されます---今回は最初のbar変数が決して閉じられません.

したがって、次のbar.open()ように、保護されたブロック内に呼び出しを配置できます。

try(Bar bar=foo.getBar())
  bar.open();
  //do something
}

それは私が望むように動作します---ほとんどの場合。しかしbar.open()、例外がスローされた場合はどうなるでしょうか。Java 7 は を閉じようとしますbarが、私の実装では、IllegalStateException一度も開かれていないものを閉じることができないため、これがスローされます。そして、そうあるべきですよね?インスタンスが開かれる前に誰かがそのBarインスタンスを閉じようとすると、何かがおかしいので、問題が伝播して未知の時期に表面化するのではなく、フェイルファーストのアプローチが必要だからです。

でも、本当は自動リソース管理を使いたいのかもしれないBar.close()ので、Bar. しかし、今私が何をしているのか見てみましょう: 構文コンパイラ シュガーを使用するためだけに API を変更しています (おそらく劣ったものにしています)。

他のアイデアはありますか?Java 7 がリソースを自動的に閉じるように Java 7 自動リソース管理を使用したいのですが、いつ開くかを決定したいと考えています

4

2 に答える 2

1

1つのアイデア

2回閉じてこれを行うのはどうですか:

try (Bar bar=foo.getBar()) {
  try(bar=bar.open()) {
    //do something
  }
}

それはまだかなり醜く、砂糖を機能させるにはいくつかのコードを書く必要があります。

別のアイデア

または、2つのクラスを持っているだけです。開くまで状態情報を保持するもの。次に、最初から作成した別のものがあり、実際に開きます。(aFileとa のようなものFileInputStreamです。)

BarInfo barInfo = foo.getBarInfo();
...
try (Bar bar = barInfo.open()) {
   // do stuff with it
}
于 2013-04-30T20:38:07.687 に答える
0

あ、持ってます!API には 2 つの異なるメソッドがあります。1 つは単にインスタンスFoo.getBar()を返すものです。Bar2 番目は になります。これは、最初に呼び出してから次のようにFoo.openBar()呼び出す便利なメソッドです。Foo.getBar()Bar.open()

public Bar openBar() {
  Bar bar=getBar();
  bar.open();
  return bar;
}

このようにして、次のように呼び出して自動リソース管理を使用できますFoo.openBar()

try(Bar bar=foo.openBar()) {
  //do something
}

Bar後で使用するインスタンスを単純に取得したい場合は、 を呼び出すことができますFoo.getBar()。残念ながら、後で開くのを待つ場合、自動リソース管理を実行することはできませんが、このアプローチは、柔軟性を維持しながら一般的なユースケースを満たすことができます。

于 2013-04-30T20:48:05.937 に答える