例外処理機能

直観が示唆するように、いくつかのことは時々機能しません。 このステートメントは、Javaの例外処理に起因する可能性があります。 さらに-利用可能なニュアンスの一部を反映した状況とコード例。


最も単純な場合、例外が発生します。

public class Test01 {
static int doTest() throws Exception {
for ( int i = 0; i < 10; i++) {
System.out.println( "i = " + i);
if (i == 3) {
throw new Exception();
}
}
return -1;
}
public static void main(String[] args) throws Exception {
System.out.println( "doTest() = " + doTest());
}
}

ここではすべてがシンプルで直感的です。

例外は発生しますが、キャッチします。

public class Test02 {
static int doTest() {
for ( int i = 0; i < 10; i++) {
System.out.println( "i = " + i);
try {
if (i == 3) {
throw new Exception();
}
} catch (Exception e) {
System.out.println( "Exception!" );
return i;
} finally {
System.out.println( "Finally block" );
}
}
return -1;
}
public static void main(String[] args) {
System.out.println( "doTest() = " + doTest());
}
}

ここでも、すべてが基本です。 finallyブロックは各反復で実行され、例外をキャッチした後、つまり、原則として、常に例外が発生したか、発生しなかった場合、メソッドを終了するかどうかを決定します。

例外が発生し、それらをキャッチして...キャンセルします。

public class Test03 {
static int doTest( int n) {
for ( int i = 0; i < n; i++) {
System.out.println( "i = " + i);
try {
if (i % 3 == 0) {
throw new Exception();
}
} catch (Exception e) {
System.out.println( "Exception!" );
return i;
} finally {
System.out.println( "Finally block" );
if (i % 3 == 0) {
if (i < 5) {
System.out.println( "Cancel exception, please" );
continue;
} else {
System.out.println( "OK, now everything is done" );
return 42;
}
}
}
}
return -1;
}
public static void main(String[] args) {
System.out.println( "doTest(2) = " + doTest(2));
System.out.println();
System.out.println( "doTest(10) = " + doTest(10));
}
}


しかし、このオプションは、インタビューで3か月間眠り込んだ瞬間を示しています。
i = 0
Exception!
Finally block
Cancel exception, please
i = 1
Finally block
doTest(2) = -1

i = 0
Exception!
Finally block
Cancel exception, please
i = 1
Finally block
i = 2
Finally block
i = 3
Exception!
Finally block
Cancel exception, please
i = 4
Finally block
i = 5
Finally block
i = 6
Exception!
Finally block
OK, now everything is done
doTest(10) = 42

finallyブロックは常に実行され、さらに、メソッドからの戻りの結果をオーバーライドしたり、戻りをキャンセルしたりできます。

そして、マルチスレッドでも?

import java.util.concurrent.*;
public class Test04 implements Runnable {
public void run() {
try {
for ( int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread() + ": " + i);
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
System.out.println( "Interrupted!" );
} finally {
System.out.println( "I'm in the finally block!" );
}
}
public static void main(String[] args) throws Exception {
Thread t = new Thread( new Test04());
t.start();
TimeUnit.SECONDS.sleep(5);
System.out.println( "main() finished" );
}
}

はいのようです:
Thread[Thread-0,5,main]: 0
Thread[Thread-0,5,main]: 1
Thread[Thread-0,5,main]: 2
Thread[Thread-0,5,main]: 3
Thread[Thread-0,5,main]: 4
main() finished
Thread[Thread-0,5,main]: 5
Thread[Thread-0,5,main]: 6
Thread[Thread-0,5,main]: 7
Thread[Thread-0,5,main]: 8
Thread[Thread-0,5,main]: 9
I'm in the finally block!


そして今-クッキー!

import java.util.concurrent.*;
public class Test05 implements Runnable {
public void run() {
try {
for ( int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread() + ": " + i);
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
System.out.println( "Interrupted!" );
} finally {
System.out.println( "I'm in the finally block!" );
}
}
public static void main(String[] args) throws Exception {
Thread t = new Thread( new Test05());
//
t.setDaemon( true );
t.start();
TimeUnit.SECONDS.sleep(5);
System.out.println( "main() finished" );
}
}

動作しません!
Thread[Thread-0,5,main]: 0
Thread[Thread-0,5,main]: 1
Thread[Thread-0,5,main]: 2
Thread[Thread-0,5,main]: 3
Thread[Thread-0,5,main]: 4
main() finished
Thread[Thread-0,5,main]: 5


プログラムが正常に終了しても、「デーモン」のようなフローでは、finallyブロックは機能しません。

はい、前述のとおり、System.exit(0)を使用してtry-catchブロックを終了すると、finallyブロックも機能しません。
up:System.exit(int)の代わりに、Runtime.getRuntime()を使用できます。

私のオリジナル

Source: https://habr.com/ru/post/J67714/


All Articles