web-dev-qa-db-ja.com

リソースで試すvsキャッチする

私はコードを見てきましたが、リソースを試してみました。以前に標準のtry-catchステートメントを使用しましたが、同じことをしているようです。だから私の質問はリソースを試すvsキャッチするそれらの違いは何ですか?.

リソースを試してみてください:

objects jar = new objects("brand");
objects can= new objects("brand");

try (FileOutputStream outStream = new FileOutputStream("people.bin")){
    ObjectOutputStream stream = new ObjectOutputStream(outStream);

    stream.writeObject(jar);
    stream.writeObject(can);

    stream.close();
} catch(FileNotFoundException e) {
    System.out.println("sorry it didn't work out");
} catch(IOException f) {
    System.out.println("sorry it didn't work out");
}
31
computerquest

Try-with-resourcesの主なポイントは、リソースが確実に閉じられるようにすることです。

Try-with-resourcesを使用しない場合、例外マスキングと呼ばれる潜在的な落とし穴があります。 tryブロックのコードが例外をスローし、finallyのcloseメソッドも例外をスローすると、tryブロックによってスローされた例外が失われ、finallyでスローされた例外が伝播されます。これは通常、残念ですが、終了時にスローされる例外は役に立たないものであり、有用な例外は有益な例外であるためです。 (つまり、どのRI制約に違反したかを示すSQLExceptionが表示される代わりに、リソースを閉じるとBrokenPipeExceptionのようなものが表示されます。)

この例外マスキングは、try-with-resourcesが発生するのを防ぐ厄介な問題です。

例外マスキングで重要な例外情報が失われないようにするために、try-with-resourcesが開発されたときに、closeメソッドからスローされた例外の処理方法を決定する必要がありました。

Try-with-resourcesでは、tryブロックが例外をスローし、closeメソッドも例外をスローした場合、 closeブロックからの例外が元の例外に追加されます

...兄弟コードブロック、特にリソースのtry-with-resourcesステートメントのtryブロックと、リソースを閉じるコンパイラー生成のfinallyブロックで、2つの独立した例外がスローされる場合があります。これらの状況では、スローされた例外の1つのみが伝播できます。 try-with-resourcesステートメントでは、このような例外が2つある場合、tryブロックから発生した例外が伝播され、tryブロックからの例外によって抑制された例外のリストにfinallyブロックからの例外が追加されます。例外がスタックを解くと、抑制された複数の例外が蓄積される可能性があります。

一方、コードは正常に完了したが、使用しているリソースが終了時に例外をスローした場合、その例外(tryブロック内のコードが何かをスローした場合は抑制されます)がスローされます。つまり、Result-with-resourcesによってResultSetまたはPreparedStatementが閉じられているJDBCコードがある場合、JDBCオブジェクトが閉じられたときにインフラストラクチャの不具合に起因する例外がスローされ、そうでなければ正常に完了する操作をロールバックできることを意味します。

Try-with-resourcesがなければ、closeメソッド例外がスローされるかどうかはアプリケーションコード次第です。 tryブロックが例外をスローしたときにfinallyブロックでスローされた場合、finallyブロックの例外は他の例外をマスクします。しかし、開発者には、クローズ時にスローされた例外をキャッチし、それを伝播しないオプションがあります。

47
Nathan Hughes

finallyブロックという何かを見逃しました。 try-with-resouces は次のようになります。

FileOutputStream outStream = null;
try {
  outStream = new FileOutputStream("people.bin");
  ObjectOutputStream stream = new ObjectOutputStream(outStream);

  stream.writeObject(jar);
  stream.writeObject(can);

  stream.close();
} catch(FileNotFoundException e) {
    System.out.println("sorry it didn't work out");
} catch(IOException f) {
    System.out.println("sorry it didn't work out");
} finally {
  if (outStream != null) { 
    try { 
      outStream.close(); 
    } catch (Exception e) {
    } 
  }
}

つまり、(neverswallow exceptions)のようなものが本当に欲しかったということです。

try (FileOutputStream outStream = new FileOutputStream("people.bin");
     ObjectOutputStream stream = new ObjectOutputStream(outStream);) {
  stream.writeObject(jar);
  stream.writeObject(can);
  // stream.close(); // <-- closed by try-with-resources.
} catch(FileNotFoundException e) {
    System.out.println("sorry it didn't work out");
    e.printStackTrace();
} catch(IOException f) {
    System.out.println("sorry it didn't work out");
    e.printStackTrace();
}
5
Elliott Frisch

唯一の違いは、tryリソースがfinallyブロックで行うようにresource.close();を自動的に追加することです。

1
Dima

Java.lang.AutoCloseableまたはJava.io.Closeableを実装するオブジェクト(クラスまたはそのスーパークラス)は、try-with-resource句でのみ使用できます。 AutoClosableインターフェースは親インターフェースであり、ClosableインターフェースはAutoClosableインターフェースを拡張します。AutoClosableインターフェースには、Exceptionをスローするcloseメソッドがあります。 catchとfinallyブロックの後に通常のtry、catch、finallyのようにtry-with-resourceを続けることもできますが、catchとfinallyブロックはtry-with-resource句内で宣言されたリソースが閉じられた後にのみ実行されます。

0
apurbojha