@ryoya828 (Ryoya)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Javaのtry-catch文の動作について質問

Q&A

Javaのtry-catch文の動作について質問

現在独学でJavaの学習をしています。
諸々の参考書を元にEclipceを使用して実際にコードを書いて実行してを繰り返しているの中で、
try-catch文で例外処理が発生するメソッドをtryブロック内に記述して、メソッドが参照するフィールドをtryブロック内から外すと実行結果がランダムになってしまう原因が分からずにおります。
フィールドをtryブロック内に含めると、cacthブロック内の処理が正常に行われます。

このランダムになる原因と、tryブロック内に含めると正常に実行される理由を教えていただきたいです。
エラーを解決するものでも無いため、調べ方が難しく是非ご助力をお願いしたく存じます。

実行結果

(1回目)
nullが検出されました。
スタックトレースここから
java.lang.NullPointerException
スタックトレースここまで
    at sukkiri_Hero/plactice.Main.main(Main.java:8)
(2回目)
nullが検出されました。
スタックトレースここから
スタックトレースここまで
java.lang.NullPointerException
    at sukkiri_Hero/plactice.Main.main(Main.java:7)

該当するソースコード

public class Main{
    public static void main(String[] args) {
        String s = null;
        try {
            System.out.println(s.length());
        }catch(NullPointerException e) {
            System.out.println("nullが検出されました。");
            System.out.println("スタックトレースここから");
            e.printStackTrace();
            System.out.println("スタックトレースここまで");
        }
    }
}
0 likes

2Answer

この質問の本質的な答えではないですが,知識として,標準出力と標準エラーを分けて吐き出せることをこの際覚えておくのもいいかもしれません.

$ java Main 1>stdout.log 2>stderr.log
$ cat stdout.log
nullが検出されました.
スタックトレースここから
スタックトレースここまで
$ cat stderr.log
java.lang.NullPointerException
	at Main.main(Main.java:5)

それぞれ別のファイルに分ければ見やすくなることもあります.

2Like

実行結果がランダムな順番で表示されるのは、2つの異なる出力ストリームを使っているせいだと思われます。

System.out.println("nullが検出されました。");
System.out.println("スタックトレースここから");
System.out.println("スタックトレースここまで");

これらは標準出力ストリーム System.out にメッセージを書き込んでいます。他方、

e.printStackTrace();

は標準エラーストリーム System.err にスタックトレースを書き込みます。1

どちらのストリームに書き込んでも最終的にターミナルに表示されますが、ストリームにバッファされた内容を書き出すタイミングが不定なために順番が入れ替わっている可能性があります。その場合、メソッドが参照するフィールド(正しくはフィールドではなくローカル変数ですが)が try ブロックの中にあるかどうかは関係ないので、正常に動いたのはたまたまランダムさが偏っただけかもしれません。

解決するにはメッセージを System.err.println() で標準エラーに書き込むようにすればいいはずです。

  1. https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Throwable.html#printStackTrace--

1Like

Your answer might help someone💌