JavaでExceptionを使って例外処理を行う方法【初心者向け】

初心者向けにJavaでExceptionを使って例外処理を行う方法について解説しています。例外処理の種類をいくつか紹介し、実際にプログラムを書いて説明しています。自分でもソースコードを書いてみて実行結果を確認してみましょう。

TechAcademyマガジンはオンラインのプログラミングスクールTechAcademy [テックアカデミー]が運営する教育×テクノロジーのWebメディアです。初心者でもすぐ勉強できる記事が2,000以上あります。

初心者向けにJavaで書くExceptionについて解説。Exceptionの書き方から実際にサンプルプログラムを書いて説明しています。

例外処理を行う際に役立つので、プログラムを書きながら理解していきましょう。

 

なお本記事は、TechAcademyのJava講座の内容をもとに作成しています。

 

田島悠介

今回はExceptionを使った例外処理について解説しよう。

大石ゆかり

田島メンター!例外処理というのは何ですか~?

田島悠介

想定外の動作が起こったときの対応を、あらかじめ指定しておくことを言うんだ。まずその予期しない状況、「例外」の具体的な場面について見ていってみようか。

大石ゆかり

分かりました!

エラーとは

いろいろな状況が考えられるので少し整理しておきましょう。

また、Javaには例外のなかにErrorというものがあったりします。これについては後述します。

 

コンパイルエラー

Javaでプログラミングをする上で一番よく出会うエラーはコンパイルエラー(文法エラー)でしょう。

タイプミスやメソッドの引数の型が違う、変数に代入する型が違っているなどが該当します。

このエラーの場合は、そもそも実行できない状態です。

 

実行時エラー

実行はできるプログラムだが、実行中に何かの理由でプログラムが異常終了してしまう、実行時エラーと言うものになります。

 

論理エラー

論理エラーと言って、実行は問題なくできるが、期待した結果になっていないという状態です。

論理エラーの場合は、一見、プログラムは正常の実行されているように見えますが、期待していた結果になっていない、ということになります。

このように一言で、エラー、と言っても様々なものがあります。

 

Exceptionとは

Exceptionは、日本語では、例外という意味になります。

プログラムは予めどういった処理をするのか、という手順を書いたものですが、状況によっては予期しない事象で正しく処理が行えないことがあります。

そのような予期しない状況をJavaでは例外(Exception)と呼んでいます。

想定外の事象をなるべく減らすためには、例外が起こった場合に備えて何かしら対応を考えておく、ということが重要です。その例外発生時に対応する処理のことを例外処理(エラーハンドリング)といいます。

続いて、その例外にはどんな種類のものがあるのかを見ていきましょう。

 

例外の種類

Javaで発生する例外は以下のようになります。

Error

システム上重大な回復不能な異常な事象。そもそも回復不能な重大な状況なので、プログラム側ではほとんど対応のしようがありません。(例:メモリ不足、スタックオーバーフロー、その他JRE自体に問題があり、JRE自体が停止する事象)

RuntimeException

実行時に起こった例外で必ずしも対処しなくても良い事象。例外処理を書くか書かないかは状況によります。プログラムのバグの可能性も多いので、プログラムを修正することが正しい対応となる場合もあります。

例えば、以下のような場合が該当します。

  • Stringの数字をintの整数に変換しようとしたがそもそも数字ではなかった(NumberFormatException)
  • インスタンスがある前提でプログラムは書かれているのに存在しなかった(NullPointerException)

Exception

上記以外の例外。例外の処理を行う必要がある。別名、検査例外、とも呼ばれます。

Exceptionの代表的な例としては、ファイルを開こうとしたが対象のファイルが存在しなかった(FileNotFoundException)、などです。

対象のファイルを開いた時にファイルが存在すれば、正常に処理が進められますが、なければ処理が進められない、つまり例外が発生したということになります。

この場合は、無いことも予め予期できるので回復可能な例外となります。

また、Exceptionは、例外処理を書かなければ、コンパイルに通らないので例外処理の記述を強制されます。これにより、想定外の状況をなるべく無くすことが可能となります。

 

[PR] Javaで挫折しない学習方法を動画で公開中

例外処理を行う方法

例外処理は以下の2つの方法があります。

  • 自分で例外を処理する
  • 自分では処理せず、例外処理を呼び出し元のクラスにスルーする

自分で例外を処理する場合は、try – catch – finally構文を使います。

finallyブロックは必要に応じて記述しましょう。

例外が発生する可能性のあるメソッドをtryブロックで囲み、catchブロックで処理したい例外を捕まえます。finallyブロックは、例外が発生してもしなくても共通で行う処理を書きます。

 

自分では処理せず、例外処理を呼び出し元のクラスに丸投げするには、メソッドのシグニチャにthrows 例外クラス名と書くだけで、呼び出し元に例外処理を丸投げできます。

つまり、例外処理を自分自身で行うのではなく、呼び出し元のメソッドでやってもらう、ということになります。

 

田島悠介

例外処理の2つの方法についてだね。

大石ゆかり

try-catchを使う場合と、throwを使う場合ですね。

田島悠介

次にそれぞれの実際の例を見てみよう。

実際に書いてみよう

自分で例外を処理する場合

下記はtest.txtというファイルを読み込もうとしている処理ですが、FileReaderクラスのオブジェクトを生成する時に対象となるファイルが存在しない場合は、以下のような例外が発生します。

FileNotFoundException

この場合は、catchブロックが該当する例外を捕まえ、そのブロック内の処理を行います(例外処理)。

次にfinallyブロックに移り、ファイルのクローズ処理を行います。finallyブロックは例外が起きなかった場合でも必ず実行されるブロックになります。

また、closeで失敗した場合、IOExceptionという例外が発生します。

ただ、ファイルクローズ時の失敗というのは結構深刻な状況ですので例外処理としてできることは殆ど無いに等しいかと思います。

finallyブロックを抜けると通常通り、以降の処理を続行します。

  FileReader reader = null;
  File file = new File("test.txt");
  try {
    reader = new FileReader(file);
    //何かしらファイルの処理が続く
    // ...
  } catch (FileNotFoundException fnfe) {
    // ファイルが見つからなかったときの例外処理
    System.out.println(fnfe);
  } catch (IOException ioe) {
    //それ以外の入出力例外処理
    System.out.println(ioe);
  } finally {
    try {
      if(reader != null) {
        reader.close();
      }
    } catch (IOException ioe) {
      // closeに失敗したときの例外処理
      System.out.println(ioe);
      throw ioe;
    }
  }
  System.out.println("ファイル処理完了");

close周りの処理が非常に複雑です。

実はJava7から try-with-resources構文と言って、自動でクローズしてくれる仕組みがあります。

こちらを使うと少し楽に書くことができます。

  File file = new File("test.txt");
  try(FileReader reader = new FileReader(file)) {
    //何かしらファイルの処理が続く
    // ...
  } catch (FileNotFoundException e) {
    // ファイルが見つからなかったときの例外処理
    System.out.println(e);
  } catch (IOException ioe) {
    //それ以外の入出力例外処理
    System.out.println(ioe);
  }
  System.out.println("ファイル処理完了");

このコードを実行すると、以下のようになります。

java.io.FileNotFoundException: test.txt (No such file or directory)
ファイル処理完了

注目すべき点は、ファイル処理完了と例外が発生しても処理を続行できているところです。

このように例外処理を行った後は、通常の処理に戻すことができます。

 

例外を呼び出し元へスルーする場合

上記の処理を呼び出し元へ丸投げするパターンにしてみましょう。

ファイルを読み込むメソッドの名前がreadメソッドだとします。

呼び出し元へスルーする場合は、メソッドのシグニチャにthrows句を記述します。

発生する例外は、

FielNotFoundException
IOException

ですので、メソッドシグニチャに以下を追記します。

throws FileNotFoundException, IOException

(FileNotFoundExceptionはIOExceptionの子クラスなのでthrows IOExceptionのみでも良いですが、今回は厳密に記述しています。)

public void read() throws FileNotFoundException, IOException {
  File file = new File("test.txt");
  FileReader reader = new FileReader(file);
  //何かしらファイルの処理が続く
  // ...
  reader.close();
  System.out.println("ファイル処理完了");
}

 

以上、Exceptionを使って例外処理を行う方法について解説しました。

どういった場合に扱う処理なのか知っておくといざという時役立つでしょう。

入門向けJavaの学習サイトもまとめているので、合わせてご覧ください。

 

田島悠介

try-catchによる処理とthrowによる処理、両方の書き方を解説したよ。

大石ゆかり

コンパイル時ではなく、プログラムの実行中に起こった問題への対応に使うのが例外処理というわけですね。

田島悠介

どのような場面で例外処理が必要になるのか、例外そのものの性質についてもよく調べておこう。

大石ゆかり

了解です。ありがとうございました!

また、オンラインのプログラミングスクールTechAcademyでは、Java講座を開催しています。

JavaやServletの技術を使ってWebアプリケーションの開発を学ぶことができます。

現役エンジニアがパーソナルメンターとして受講生に1人ずつつき、マンツーマンのメンタリングで学習をサポートし、最短4週間で習得することが可能です。