116

Javaには、休止状態でセッションを開くときに使用できるusingステートメントがありますか?

C# では次のようになります。

using (var session = new Session())
{


}

したがって、オブジェクトはスコープ外になり、自動的に閉じます。

4

12 に答える 12

138

Java 7は、この機能をJavaプラットフォームにもたらす自動リソースブロック管理を導入しました。以前のバージョンのJavaには、に似たものはありませんでしたusing

java.lang.AutoCloseable例として、次の方法で実装する任意の変数を使用できます。

try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
    ...
}

java.io.Closeableストリームによって実装されるJavaのインターフェースは自動的に拡張されるため、C#ブロックで使用するのと同じようAutoCloseableに、ブロックでストリームを使用できます。これはC#と同等です。tryusingusing

バージョン5.0以降、Hibernate Sessionsは実装さAutoCloseableれ、ARMブロックで自動クローズできます。以前のバージョンのHibernateSessionはを実装していませんでしたAutoCloseable。したがって、この機能を使用するには、Hibernate>=5.0である必要があります。

于 2010-01-06T21:17:31.873 に答える
32

Java 7 より前は、Java にそのような機能はありませんでした (Java 7 以降については、 ARMに関するAsaphの回答を参照してください)。

あなたはそれを手動で行う必要があり、それは苦痛でした:

AwesomeClass hooray = null;
try {
  hooray = new AwesomeClass();
  // Great code
} finally {
  if (hooray!=null) {
    hooray.close();
  }
}

// Great codeそして、それはどちらもhooray.close()例外をスローできない場合の単なるコードです。

変数のスコープを本当に制限したいだけなら、単純なコード ブロックがその役割を果たします。

{
  AwesomeClass hooray = new AwesomeClass();
  // Great code
}

しかし、それはおそらくあなたが意図したものではありません。

于 2010-05-31T12:39:22.490 に答える
20

Java 7 以降: http://blogs.oracle.com/darcy/entry/project_coin_updated_arm_spec

問題のコードの構文は次のようになります。

try (Session session = new Session())
{
  // do stuff
}

またはその(多くの)サブインターフェースの1つSessionを実装する必要があることに注意してください。AutoClosable

于 2011-08-24T08:17:41.093 に答える
8

技術的に:

DisposableObject d = null;
try {
    d = new DisposableObject(); 
}
finally {
    if (d != null) {
        d.Dispose();
    }
}
于 2010-01-06T21:18:13.923 に答える
8

最も近いJavaの同等物は

AwesomeClass hooray = new AwesomeClass();
try{
    // Great code
} finally {
    hooray.dispose(); // or .close(), etc.
}
于 2010-05-31T12:40:30.593 に答える
3

今のところ、ありません。

ただし、ARM forJava7の提案があります。

于 2010-01-06T21:20:51.163 に答える
3

リソース管理に関心がある場合は、Project Lombok@Cleanupで注釈が提供されています。サイトから直接取得:

@Cleanupコード実行パスが現在のスコープを終了する前に、特定のリソースが自動的にクリーンアップされるようにするために使用できます。これを行うには、ローカル変数宣言に次の@Cleanup ような注釈を付けます。

@Cleanup InputStream in = new FileInputStream("some/file");

その結果、現在のスコープの最後でin.close()が呼び出されます。この呼び出しは、try/finally コンストラクトによって実行されることが保証されています。以下の例を見て、これがどのように機能するかを確認してください。

クリーンアップしたいオブジェクトのタイプにclose() メソッドがなく、他の引数のないメソッドがある場合は、このメソッドの名前を次のように指定できます。

@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);

デフォルトでは、クリーンアップ方法は であると想定されています close()。引数を取るクリーンアップ メソッドは、 経由で呼び出すことはできません @Cleanup

バニラジャワ

import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    InputStream in = new FileInputStream(args[0]);
    try {
      OutputStream out = new FileOutputStream(args[1]);
      try {
        byte[] b = new byte[10000];
        while (true) {
          int r = in.read(b);
          if (r == -1) break;
          out.write(b, 0, r);
        }
      } finally {
        out.close();
      }
    } finally {
      in.close();
    }
  }
}

ロンボクと

import lombok.Cleanup;
import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }
  }
}
于 2010-05-31T13:13:34.007 に答える
2

いいえ、Javaにはusing同等のステートメントはありません。

于 2010-01-06T21:18:03.597 に答える
1

このJava キーワードのリスト を参照してください。

  1. 残念ながら、このusingキーワードはリストに含まれていません。
  2. usingまた、Java では現在のところ、C# のキーワードと他のキーワードとの同等性はありません。

"using"このような動作を模倣try...catch...finallyするには、 内のリソースを破棄するブロックを使用する必要がありますfinally

于 2010-05-31T12:41:44.790 に答える
1

プロジェクト コインのARM ブロックはJava 7 になります。これは、構文を使用して .Net と同様の機能を Java にもたらすことを目的とした機能です。

于 2010-05-31T12:42:52.537 に答える
0

変数を自動的に閉じる/破棄することについて話す代わりに、変数のスコープを制限することに関する質問に答える。

Java では、中かっこを使用して閉じた匿名スコープを定義できます。とてもシンプルです。

{
   AwesomeClass hooray = new AwesomeClass()
   // Great code
}

変数hoorayはこのスコープ内でのみ使用でき、外部では使用できません。

これは、一時的な繰り返し変数がある場合に役立ちます。

たとえば、それぞれにインデックスがあります。item変数が for ループで閉じられている (つまり、ループ内でのみ使用可能である) のと同様に、変数indexは無名スコープで閉じられています。

// first loop
{
    Integer index = -1;
    for (Object item : things) {index += 1;
        // ... item, index
    }
}

// second loop
{
    Integer index = -1;
    for (Object item : stuff) {index += 1;
        // ... item, index
    }
}

また、変数のスコープを提供する for ループがないが、一般的な変数名を使用したい場合にも、これを使用することがあります。

{
    User user = new User();
    user.setId(0);
    user.setName("Andy Green");
    user.setEmail("andygreen@gmail.com");
    users.add(user);
}

{
    User user = new User();
    user.setId(1);
    user.setName("Rachel Blue");
    user.setEmail("rachelblue@gmail.com");
    users.add(user);
}
于 2013-09-26T13:34:46.793 に答える