2017-12-18 8 views
1

なぜ次のコードはコンパイルされますが、呼び出されるメソッドはExceptionを投げる必要はありませんか? Exceptionはチェックされた例外ではなく、未チェックの例外ではありませんか?どうか明らかにしてください。例外をスローしてキャッチする必要はありませんが、IOExceptionは

class App { 
    public static void main(String[] args) { 
     try { 
      amethod(); 
      System.out.println("try "); 
     } catch (Exception e) { 
      System.out.print("catch "); 
     } finally { 
      System.out.print("finally "); 
     } 
     System.out.print("out "); 
    } 
    public static void amethod() { } 
} 

私はIOexceptionとトライキャッチ(チェック例外)を使用したい場合は、この方法がIOExceptionをスローする必要があると呼ばれています。私はこれを得る。

import java.io.IOException; 

class App { 
    public static void main(String[] args) { 
     try { 
      amethod(); 
      System.out.println("try "); 
     } catch (IOException e) { 
      System.out.print("catch "); 
     } finally { 
      System.out.print("finally "); 
     } 
     System.out.print("out "); 
    } 
    public static void amethod() throws IOException { } 
} 
+2

あなたの理解は後ろ向きだと思います。 'throws'宣言は、呼び出し側がキャッチする例外ではなく、呼び出し側によってスローされる、チェックされた例外をリストすることを意図しています。 –

答えて

1

「例外」チェック例外なくチェックされない例外ではないですか?

はい、そうです。

しかし、我々は方法がException自体をスローしません知っている場合でも、コードcatch(Exception e){はまだ実行する可能性があります。 tryブロック内のコードは、まだExceptionから継承するものを投げる可能性があります。これにはRuntimeExceptionとそのサブクラスが含まれますが、これはチェックされません。

catch(IOException e){は、一方、チェック例外を捕捉することができます。コンパイラは、tryブロック内のコードのどれもIOExceptionを投げることができないことをかなり容易に理解することができます(以後、IOExceptionのサブクラスはRuntimeExceptionのサブクラスにはなりません)。チェックされた例外をスローするメソッドであれば、コードにフラグを立てることができるように明示的にそうしなければなりません。

+0

完璧!理解しやすい –

1

あなたが観察している動作は、Java言語仕様がこの状況で特別にExceptionを処理するという事実から来ています。 §11.2.3によると:

catch節チェック例外クラスEをキャッチすることができれば、コンパイル時エラーが発生すると、それはcatchに対応するtryブロックを投げることができるとは限りません E がExceptionまたはExceptionのスーパークラスでない限り、E 1のサブクラスまたはスーパークラスであるチェック済み例外クラス。

Exception(およびそのスーパークラスThrowable)もRuntimeExceptionを拡張する例外をキャッチするために使用することができますので、これは合理的です。実行時の例外は常に可能であるため、コンパイラは、チェックされた例外の有無にかかわらず、Exceptioncatch節に常に表示させます。

関連する問題