2011-01-12 10 views
1

今日、私はこの模擬例に似たコードスニペットを見直さなければなりませんでした。最後に例外にネストされた振る舞い

package test;

import java.io.IOException; 
import org.apache.log4j.Logger; 

public class ExceptionTester { 

    public static Logger logger = Logger.getLogger(ExceptionTester.class); 

public void test() throws IOException { 
    new IOException(); 
} 

public static void main(String[] args) { 
    ExceptionTester comparator = new ExceptionTester(); 
    try { 
     try { 
      comparator.test(); 
     } finally { 
      System.out.println("Finally 1"); 
     } 
    } catch(IOException ex) { 
     logger.error("Exception happened" ex); 
      // also close opened resources 
    } 
    System.out.println("Exiting out of the program"); 
} 

}

内側trycatchブロックを持っていなかったので、次output.Iは、コンパイルエラーを予想印刷しています。

 
Finally 1 
Exiting out of the program 

IOExceptionが外側catchブロックでキャッチされた理由を私は理解していません。それはちょうど新しいIOExceptionが(作成) - 誰もがこれを説明することができれば、私は、私は、問題があなたの関数

public void test() throws IOException { 
    new IOException(); 
} 

が実際に例外をスローしないことだと思います特に、スタックアンワインドプロセス

+4

「試行」には、> = 1の「キャッチ」__および/または__ a「最後に」が必要です。 'catch 'は必須ではありません。 – dkarp

答えて

6

finallyブロックは、正常条件と異常条件の両方で実行する必要があるタスクを表します。

例:面接候補者を昼食に服用します。昼食を取っている間、彼は殺人事件で警察に欲しいと分かっています。例外!昼食は終わった、インタビューは完全な損失ですが、...あなたはまだ昼食を支払う必要があります。

try { 
    meetForLunch(interviewCandidate); 
} 
finally { 
    lunchBill.pay(); 
} 

昼食のために支払うことは例外の世話をしていないことに注意してください、あなたはまだあなたのインタビューで、殺人者についての何かを持っています。ダメージコントロールで処理する前に世話をしなければならないゆるい終わりです。

ほとんどfinallyブロックがそのように使用されます。ファイルには、データを正常に保存されているか否かクローズする必要があり、データベース接続はトランザクションが承認されたかどうかをクローズする必要かどうか、など

そして、例外は囲むスコープ内で一致するcatchブロックを探して、その奇妙な方法で外側に続きます。

finallyブロックは、を実行します。 tryブロックが実行中に終了しない限り、このブロックは常に実行されます。

+0

もちろん、候補者があなたを昼食に殺すと、この類推は崩壊します。 :-) –

+5

@Stephen:あなたは最後の文を逃したと思う。 –

+0

@Ben Voight - レストランに関する限り、プロセスは終了していません。 –

0

を挙げて、いただければ幸いですオブジェクト。これを修正するには

public void test() throws IOException { 
    throw new IOException(); 
} 

に修正する必要があります。

+1

「例外が発生しました」というのは印刷されませんでしたが、「finally」ブロックには関係しません。 –

0

上記のコードは、あくまでも説明のを必要としません。コールスタックはあまり関係ありません。あなたの混乱は何ですか?私は何かが恋しいですか?ここ はあなたがキャッチして finallyブロックの両方を必要としない私の説明

まずポイント

  • です。 のいずれか、またはその両方に、 tryブロックを使用できますが、そのいずれも使用できません。
  • tryまたはcatchブロック内で 例外がスローされた場合でも、finally句 のコードは常に実行されます。コード内に tryステートメントまたは catchブロック内のreturn文がある場合、 finallyブロック内のコードはメソッドから返される前に に実行されます。
  • (あなたが test()方法で throwを使用していないので)ので、上記のコードでは、例外がスローされることはなかった

しかし、言語仕様によって約束としてfinallyブロックが実行されてしまった、あなたは出力Finally 1を得ました。実行順序の次のステートメントは、catchブロックが到達していないため、IOExceptionが存在しないため、System.out.println("Exiting out of the program");です。したがって、Exiting out of the programが印刷されます。

関連する問題