例外伝播とは Google で検索してみましたが、満足のいく結果が見つかりませんでした。できればJavaの観点からこれを説明してください。
7 に答える
驚くべきことに、例外についての Java チュートリアル ページで説明されています。
例外は、キャッチされるまで、メソッドからメソッドへ、コール スタックを上って伝播します。したがって、 if 、 which 、 which 、および ifが例外をスローした場合、これらのメソッドのいずれかが例外をキャッチしない限り、例外a()
はd から c 、 b 、および a に伝播します。b()
c()
d()
d()
簡単な回答:キャッチされなかった例外は、スタックが空になるまでコール スタックに伝播されます。この伝播は、例外伝播と呼ばれます。
長い答え: メソッドが例外をスローした後、ランタイム システムはコール スタックを検索して、例外を処理できるコード ブロック (例外ハンドラ) を含むメソッドを探します。検索は、エラーが発生したメソッドから開始され、メソッドが呼び出されたときとは逆の順序でコール スタックを進みます。適切なハンドラーが見つかると、ランタイム システムは例外をハンドラーに渡します。また、注目すべき点があります。
method3() が method2() を呼び出し、method2() が method1() を呼び出す一連のメソッドがあるとします。そうするとき
1) method3() で例外が発生し、method3() には例外ハンドラがありません。
2) キャッチされなかった例外は、スタック内で下方に伝搬されます。つまり、method2() 内の適切な例外ハンドラがチェックされます。
3) 再び method2 で例外ハンドラーがない場合、再び例外が method1() に伝播され、そこで例外ハンドラーが見つかります。
例:
class ExceptionPropagation{
void method3(){
int result = 100 / 0; //Exception Generated
}
void method2(){
method3();
}
void method1(){
try{
method2();
} catch(Exception e){
System.out.println("Exception is handled here");
}
}
public static void main(String args[]){
ExceptionPropagation obj=new ExceptionPropagation();
obj.method1();
System.out.println("Continue with Normal Flow...");
}
}
出力:
例外はここで処理されます
通常の流れを続行...
未チェックの例外のみが伝搬されます。チェックされた例外がコンパイル エラーをスローする
[1] http://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html
メソッドが呼び出されるたびに、スタックが形成され、最初にスタックの一番上から例外がスローされます。例外がキャッチされない場合は、キャッチされなくなるまでスタックを下って前のメソッドに移動し始めます。スタックの一番下に到達した後も例外がキャッチされない場合、例外は JVM に伝播され、プログラムは終了します。
チェックされていない例外は、Java で自動的に伝播されます。プログラム >
public class ExceptionTest {
public static void main(String[] args) {
method1();
System.out.println("after calling m()");
}
static void method1() {
method2();
}
static void method2() {
method3();
}
static void method3() {
throw new NullPointerException();
}
}
チェックされた例外を伝播するには、メソッドは throws キーワードを使用して例外をスローする必要があります。プログラム >
public class ExceptionTest {
public static void main(String[] args)
throws FileNotFoundException {
method1();
System.out.println("after calling m()");
}
static void method1() throws FileNotFoundException{
method2();
}
static void method2() throws FileNotFoundException{
method3();
}
static void method3() throws FileNotFoundException{
throw new FileNotFoundException();
}
}
未チェックの例外 (NullPointerException) の伝播 >
throws キーワードを使用したチェック済み例外 (FileNotFoundException) の伝播 >
から: http://www.javamadesoeasy.com/2015/05/exception-propagation-in-java-deep.html
例外が発生すると、例外がスタックの一番上から一番下にドロップされ、呼び出しチェーンにドロップされてカットされるプロセスであり、そこでキャッチされない場合、例外は再び前のメソッドにドロップされますなど、キャッチされるまで、または呼び出しスタックの一番下に到達するまで続きます。これは、例外の伝播と呼ばれます。
たとえば、スタックが次のようになっているとします。
c()
b()
()
主要()
c() メソッドで例外が発生し、それが処理されない場合は前の b() メソッドに伝播され、そこで処理されない場合は、例外が処理される a() メソッドに再び伝播されます。
例外は、main() メソッド、a() メソッド、b() メソッド、または c() メソッドのコール スタック内の任意のメソッドで処理できます。
スレッドに返信
別のオブジェクトを呼び出すオブジェクトがあり、次にそのオブジェクトが別のオブジェクトを呼び出すとします。呼び出されたオブジェクトのいずれかで例外がスローされ、それがキャッチされない場合、例外は呼び出し元のメソッドに伝播します(どこにもキャッチされない場合は、アプリケーションがクラッシュします)。
class MyClass{
void myMethod(){
A a = new A();
a.doSomething(0);
}
}
class A{
double doSomething(int n){
return 1/n;
}
}
メソッドが実行されると、オブジェクトのメソッドでmyMethod
例外がスローされ、例外はスタック内の呼び出し元のメソッドに伝播します(したがって、この例では例外はのに伝播します)。doSomething
A
myMethod
myClass
プログラムの構築において、エラーが発生した場所は、それを処理するのに最適な場所ではありません。つまり、エラーは、発生した場所ではなく、その場所で処理されます。