25

私はJava初心者で、次の典型的なJavaコードがあるかどうか疑問に思っていました

public class MyApp {
  public static void main(String[] args) {
    try {
      // do stuff
    } catch {
      // handle errors
    } finally {
      // clean up connections etc.
    }
  }
}

JVM は、finally ブロックが常に実行されることを保証しますか? 私がどこから来たのかを理解するために、NULL ポインターを逆参照し、その後実行するコードがない場合にクラッシュする可能性のある C/C++ プログラムに慣れています。

しかし、Java と GC/マネージ メモリ ビジネス全般を理解しているので、null ポインターの逆参照などはありません。 、またはありますか?たとえば、Pythonでは、通常、

try:
  # do stuff
except AnExceptionIKnewMightHappen:
  # react in an appropriate way
except:
  # log that weird error I had not known could happen

そして、コードを通過せずにアプリが死ぬことは一度もありません。

もちろん、OS がなんらかの理由でプロセスを強制終了した場合 (またはプラグを抜くなど、何かがシステム全体を強制終了した場合)、Java にできることはあまりありません。また、PHP から、インタープリターが発生した後もまだそこにあったとしても、保護できないキャッチ不能なエラーを知っています (少なくとも、適切なメッセージを出力することができます)。

編集:わかりやすくするために(誰も誤解していませんでした)、最終的にバイパスされる可能性のあるコード内のものを探していたことを付け加えさせてください。System.exit を指すことは、なぜそのようなことをしたいのかわかりませんが、参考になりました。

JVMの終了はかなり明白な方法であり、私はそれを外的原因として数えます。JVM とアプリの実行中にスレッドが終了する可能性も覚えておく必要があることを指摘するメモは、非常に役に立ちました。

4

10 に答える 10

47

ここにリストされているメモを除いて、基本的にはい(私の強調):

try または catch コードの実行中に JVM が終了すると、finally ブロックが実行されない場合があります。同様に、try または catch コードを実行しているスレッドが中断または強制終了された場合、アプリケーション全体が続行されても、finally ブロックが実行されない可能性があります。

于 2009-02-05T14:15:39.240 に答える
13

以下は保証されません。

public class Main {
    public static void main(String args[]) {
        try {
            System.out.println("try");
            System.exit(0);
        } catch (Exception e) {
            System.out.println("exception");
        } finally {
            System.out.println("finally");
        }
    }
}

それを実行します。

于 2009-02-05T14:17:53.153 に答える
10

一言で言えば、そうです。

Java の finally ブロック内のコードは、次の場合を除いて常に実行されます。

  • try または catch ブロック中に JVM が終了する
  • コードを実行しているスレッドが、try または catch ブロック中に中断または強制終了された

(から: http://java.sun.com/docs/books/tutorial/essential/exceptions/finally.html )

そのため、明示的に System.exit(int) を呼び出すか、プロセスまたはスレッドを外部で強制終了しない限り、信頼できます。

于 2009-02-05T14:17:56.303 に答える
4

もちろん、その finally ブロックは毎回実行されます。JVM クラッシュまたは exit() 関数が呼び出された場合を除きます。Java アプリケーションがセグメンテーション違反を起こした JNI ネイティブ コードを呼び出したコードがありました。結果として発生したクラッシュにより、JVM が強制終了され、finally が実行できなくなりました。

于 2009-02-05T14:18:10.937 に答える
2

クリス・キャメロンは正しいです。しかし、通常はfinally-block が実行されます。Java には null ポインターの逆参照が存在します。

try {
    List<Object> x = null;
    x.get(1); //throws the unchecked NullPointerException
} finally {
    //will be executed
}

finally ブロックが実行されます。

于 2009-02-05T14:20:38.607 に答える
1

はい、JVM は常にそれを実行します。保証付き。

もちろん... JVM自体が停止した場合(例:System.exit())、何も保証する立場にはありません。しかし、JVM の停止は Java 内の問題ではありません。

于 2009-02-06T05:21:49.973 に答える
0

finally ブロックが実行されない唯一の例外は、JVM クラッシュまたは system.exit() のいずれかです。

于 2010-11-01T03:35:41.973 に答える
0

はい、JVM のクラッシュがない限り、finally ブロックは常に実行されます (非常にまれですが、発生する可能性があります)。

于 2009-02-05T14:15:44.873 に答える