いくつかのC#で投稿された質問で、「using」句への参照を見てきました。javaには同等のものがありますか?
12 に答える
はい。Java 1.7 では、try-with-resourcesコンストラクトが導入され、次のように記述できるようになりました。
try(InputStream is1 = new FileInputStream("/tmp/foo");
InputStream is2 = new FileInputStream("/tmp/bar")) {
/* do stuff with is1 and is2 */
}
using
…という発言のように。
残念ながら、Java 1.7 より前の Java プログラマーは、try{ ... } finally { ... } の使用を余儀なくされていました。Java 1.6 の場合:
InputStream is1 = new FileInputStream("/tmp/foo");
try{
InputStream is2 = new FileInputStream("/tmp/bar");
try{
/* do stuff with is1 and is 2 */
} finally {
is2.close();
}
} finally {
is1.close();
}
はい、Java 7 以降、次のように書き換えることができます。
InputStream is1 = new FileInputStream("/tmp/foo");
try{
InputStream is2 = new FileInputStream("/tmp/bar");
try{
/* do stuff with is1 and is2 */
} finally {
is2.close();
}
} finally {
is1.close();
}
として
try(InputStream is1 = new FileInputStream("/tmp/foo");
InputStream is2 = new FileInputStream("/tmp/bar")) {
/* do stuff with is1 and is2 */
}
パラメータとして try ステートメントに渡されるオブジェクトは、実装する必要があります。公式ドキュメントjava.lang.AutoCloseable
を参照してください。
この言語で最も近いのは、try-finally を使用することです。
using (InputStream in as FileInputStream("myfile")) {
... use in ...
}
になる
final InputStream in = FileInputStream("myfile");
try {
... use in ...
} finally {
in.close();
}
一般的な形式は常に次のとおりです。
acquire;
try {
use;
} finally {
release;
}
取得が try ブロック内の場合、取得に失敗した場合に解放されます。場合によっては、不必要なコード (通常は上記の例で null をテストする) をハックできるかもしれませんが、たとえば ReentrantLock の場合、悪いことが起こります。
同じことを頻繁に行う場合は、「execute around」イディオムを使用できます。残念ながら、Java の構文は冗長なので、大げさな表現がたくさんあります。
fileInput("myfile", new FileInput<Void>() {
public Void read(InputStream in) throws IOException {
... use in ...
return null;
}
});
どこ
public static <T> T fileInput(FileInput<T> handler) throws IOException {
final InputStream in = FileInputStream("myfile");
try {
handler.read(in);
} finally {
in.close();
}
}
より複雑な例は、たとえばラップ例外です。
それには長い時間がかかりましたが、Java 7 では、 AutoCloseableインターフェイスとともに、 try-with-resources ステートメントが追加されました。
私が知っているわけではありません。try...finally ブロックでいくらかシミュレートできますが、それでもまったく同じではありません。
Java で得られる最も近いものは、try/finally です。また、Java は暗黙の Disposable 型を提供しません。
C#: using ブロックの外側の変数のスコープ
public class X : System.IDisposable {
public void Dispose() {
System.Console.WriteLine("dispose");
}
private static void Demo() {
X x = new X();
using(x) {
int i = 1;
i = i/0;
}
}
public static void Main(System.String[] args) {
try {
Demo();
} catch (System.DivideByZeroException) {}
}
}
Java: ブロック外の変数のスコープ
public class X {
public void dispose() {
System.out.println("dispose");
}
private static void demo() {
X x = new X();
try {
int i = 1 / 0;
} finally {
x.dispose();
}
}
public static void main(String[] args) {
try {
demo();
} catch(ArithmeticException e) {}
}
}
C#: ブロック内の変数のスコープ
public class X : System.IDisposable {
public void Dispose() {
System.Console.WriteLine("dispose");
}
private static void Demo() {
using(X x = new X()) {
int i = 1;
i = i/0;
}
}
public static void Main(System.String[] args) {
try {
Demo();
} catch (System.DivideByZeroException) {}
}
}
Java: ブロック内の変数のスコープ
public class X {
public void dispose() {
System.out.println("dispose");
}
private static void demo() {
{
X x = new X();
try {
int i = 1 / 0;
} finally {
x.dispose();
}
}
}
public static void main(String[] args) {
try {
demo();
} catch(ArithmeticException e) {}
}
}
匿名の内部クラスを実装して、「using」ブロックに似たものを実現できると思います。Springが「Dao Templates」で行うように。
Java で BGGA クロージャを取得すると、これは Java の同様の構造にも開かれます。ガフターはこの例をスライドで使用しています。たとえば、次のとおりです。
withLock(lock) { //closure }
とにかく、使用はシンタックス シュガーなので、Java 仲間の皆さん、気にしないでください。
最初の例でほとんどのプログラマーが使用する実際のイディオムは次のとおりです。
InputStream is1 = null;
InputStream is2 = null;
try{
is1 = new FileInputStream("/tmp/bar");
is2 = new FileInputStream("/tmp/foo");
/* do stuff with is1 and is 2 */
} finally {
if (is1 != null) {
is1.close();
}
if (is2 != null) {
is2.close();
}
}
このイディオムを使用するとインデントが少なくなります。これは、クリーンアップするリソースが 2 つを超える場合にさらに重要になります。
また、必要に応じて new FileStream() がスローする例外を処理する構造体に catch 句を追加することもできます。最初の例では、これを行うには、別の外側の try/catch ブロックが必要です。
いいえ、ありません。
あなたはできる
public void func(){
{
ArrayList l = new ArrayList();
}
System.out.println("Hello");
}
これにより、using 句のスコープが制限されますが、ファイナライズ コードを呼び出すための IDisposable インターフェイスはありません。try{}catch(){}Finally{} を使用できますが、それを使用するだけの価値はありません。ちなみに、Java でファイナライザーを使用することは、一般的には悪い考えです。
いいえ、Java での使用はありません。最も類似した機能は「インポート」キーワードです。