Java の例外処理まとめ.

Java Exception: 文法

try

例外を捕まえるための範囲 (コンテキスト) を作る. {}で囲まれた部分がコンテキストになる.

catch

try{}で作成したコンテキスト内で発生した例外を捕まえたあとに処理する内容を書く. エラーログを吐くとか.

finally

最後にかならず実施したい処理を書く.

例えば IO ファイルを Open して処理している途中で異常が発生したとき, ファイルを閉じる処理など.

try と catch の例

try 文には正常系を, catch 文には異常系を書く.

こうすることで,

正常系のコードと異常系のコードを明確に分ける

ことができる (そして, 異常系は後回し…)

try {
  hoge ()
} catch (FooException e1) { // 例外クラス 変数名
  e1.printStackTrace ();
} catch (BarException e2) { // 例外クラス 変数名
  e2.printStackTrace ();
} finally {
  // 任意
}

printStackTrace () メソッドを書くと, 例外発生時のスタックトレースを表示できる.

throw

throw 文をつかうと, 自分で例外を投げることができる. 引数にメッセージをわたすこともできる.

throw new HogeException ("秘密のメッセージ");

Java 例外クラス

Java では例外はクラスとして実装する.

Throwable クラスを継承するかたちで, 各例外クラスが定義されている.

  • Throwable
    • Error
    • Exception
      • RuntimeException

java.lang.Object. java.lang.Throwable. java.lang.Exception. java.io.IOException. java.io.FileNotFoundException.

以下のようなサブクラスで小分類されている.

  • Throwable
    • Error: 処理の継続不可. 致命的なエラー
    • Exception: 検査例外, コンパイル時に例外処理の実装が強制される
      • RuntimeException: 実行時例外. コンパイル時に例外処理の実装が強制されない

Errorクラス

プログラムではどうすることもできない事態が起きた際に発生.

  • メモリ不足の場合: OutOfMemoryError
  • スタック領域がオーバーフローした場合: StackOverflowError
  • ファイルが壊れている場合: ClassFormatError

Exception クラス(検査例外/チェック例外)

try-catchが必要な例外で実装しないとコンパイルエラーになる. EclipseとかのIDEだといきなりズラッと保管されたり赤くなったりするアレ.

  • 入出力関係の例外: IOException
  • DB関係の例外: SQLExcetion

🔖検査例外

RuntimeExceptionクラス

Throwable

Throwableクラスのメソッドまとめ.

例外クラスはThrowableクラスを継承しており, ここで定義されているメソッドで情報取得できる.

  • getMesssage(): エラーメッセージを取得
  • getCause(): 実際に発生した例外を取得
  • printStackTrace(): スタックトレース表示

Java 例外のトピック

独自定義の例外

Java の例外はクラスなので, 上のクラスを継承したクラスを定義することで, 独自例外を作成できる.

Error と RuntimeException は, Java 仮想マシンが通知してくる特別な例外なので, 一般のプログラマは, 以下のどちらかで定義.

  • Java API で用意されている Exception のサブクラスを使う
  • java.lang.Exception Exception のサブクラスを自分で定義する
class MyException extends Exception {}

こんな風にかけば, 上位のコンテキストにエラーコードを渡すことができる. catch ブロックで発生したエラーによって, 処理を分岐できる. しかし, 分岐するならば, 例外クラスを定義した方がエレガントだ.

import java.lang.Exception;
public class MyErrorSample {
        public static void main (String args[]) {
                try {
                        throw new MyException (5);
                }
                catch (MyException e) {
                        e.printStackTrace ();
                        System.out.println ("ErrorCode = " + e.getCode ());
                }
        }
}
 
class MyException extends Exception {
        int errorCode;
 
        MyException (int errorCode) {
                this.errorCode = errorCode;
        }
 
        int getCode () {
                return errorCode;
        }
}

Java の標準的な例外クラス

例外処理をしたいときなにを throw すればいいのか. Effective Java には独自定義の例外よりも標準例外を利用するようにと書いてある.

  • みんな知っているから
  • パフォーマンスが軽くなるから

標準的に利用される Java の例外を以下にまとめてみる.

DefinitionDescriptionExample
java.lang.IllegalArgumentException不適切な引数パラメータエラー
java.lang.IllegalStateException不正な状態未初期化で呼び出し
java.lang.NullPointerException.Null アクセス
java.lang.IndexOutOfBoundsException範囲外配列の Index オーバ
java.util.ConcurrentMdificationExceptionマルチスレッドアクセス並行処理漏れ
java.lang.UnsupportedOperationException未サポート機能未サポートなのにメソッドが呼ばれた

自分で利用しないまでも, よくみかける例外が以下にまとまっている. デバッグの友.

Java通信タイムアウトまとめ

Exceptionとそのメッセージを収集していく.

🔖通信タイムアウト

java.io.EOFException: SSL peer shut down incorrectly

通信相手から接続が切られる.

ref. 【エラー解決方法】バッチ処理実行時にSSLExceptionが発生!?を解決する方法 | 株式会社AMG Solution

このケースでは接続処理が長かったからとか.


これ書くと直る?

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");

ref. tomcat6 - Java 1.8 and tomcat 6.0.53 Caused by: java.io.EOFException: SSL peer shut down incorrectly - Stack Overflow

java.net.SocketException: Broken pipe

to. Broken pipe

java.net.ConnectException

接続拒否エラー.

これはクライアントからサーバへの通信が届いていない. 原因はサーバかその途中の通信経路. pingをしたりリトライしてみて実験して切り分ける.

ConnectException (Java Platform SE 8)

負荷によって届かないならばタイムアウト値を調整してみる.

References