Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

throwとは

例外的状況が発生したどうかはJVMが監視しており、JVMが例外的状況を検知すると処理をcatchブロックに移します。

この例外を監視しているJVMに対して、意図的に「Exceptionという例外的状況になりました」と報告することも可能です。

例外を報告するのに使われるのが throw キーワードです。

監視しているJVMに対して例外的状況を報告することを「例外を投げる」もしくは「例外を送出する」と言います。

例外が投げられると、JVMは例外を検知し、即時でcatchブロックの実行や伝播に処理を移行します。

では、例外インスタンスを自分で投げるサンプルを確認してみます。

■記述例
public class Main {
  public static void main(String args[]){
    Member m = new Member();
    m.setAge(-26);
  }
}
class Member {
  int age;
  void setAge(int age) {
    if (age < 0) {
      throw new IllegalArgumentException("年齢は正の数を指定してください。指定値=" + age);
    }
    this.age = age;
  }
}

Memberクラス の setAgeメソッド では、引数を age に代入しています。

年齢に負の値が入ることはないため、 age が負の値になるのを防ぐために代入前に引数を検査する形にしました。

もし、引数に負の値が代入されている場合、IllegalArgumentException インスタンスを投げることで「引数の値が異常値であるため処理が継続できない」という例外的状況が発生していることを、JVMに報告します。

setAgeメソッド で生じた例外は、呼び出し元の mainメソッドに伝播しますが、mainメソッドでは例外をキャッチしていないため、JVMがプログラムを強制的に終了します。

実行結果は次の通りです。

■実行結果
mbp:desktop potepan$ java Main
Exception in thread "main" java.lang.IllegalArgumentException: 年齢は正の数を指定してください。指定値=-26
at Member.setAge(Main.java:12)
at Main.main(Main.java:4)

throwの処理の流れ

先述した例外の説明の内容から、throwの処理の流れをまとめると下記の通りです。

例外発生 → 例外オブジェクト生成 → 例外のスロー → 例外のキャッチ

参考までに、Throwableクラスのリファレンス文も掲載します。

Throwableクラスは、Java言語のすべてのエラーと例外のスーパー・クラスです。このクラス(またはそのサブクラスの内の1つ)のインスタンスであるオブジェクトだけがJava仮想マシンによってスローされるか、Javaのthrow構文によってスローされます。同じように、このクラスまたはそのサブクラスの内の1つだけがcatch節の引数の型に指定できます。
(中略)
2つのサブクラスErrorとExceptionのインスタンスは従来、例外的な状況が発生したことを示すために使用されます。これらのインスタンスは、通常、関連する情報(スタック・トレース・データなど)を格納するために、例外的な状況に応じて新しく作成されます。
スロー可能オブジェクトには、作成時のそのスレッドの実行スタックのスナップショットが含まれます。これには、エラーについての詳細情報を示すメッセージ文字列を含めることもできます。

※参考:Throwable (Java Platform SE 8)

throwとthrowsの違いは?

Javaの例外処理には、先述した「throw」と「throws」という処理があります。

両者ともその名前の通り、処理を「投げる」という意味合いを持っています。

しかし、名前は似ている「throw」と「throws」ですが、処理内容には大きな違いがあるのです。

「throw」と「throws」の違い
  • throwは、例外を意図的に発生させて、例外処理を実行させることができます。
  • throwsは、メソッド内で例外が発生した場合、自身のメソッド内でcatchするのではなく呼び出し元に例外を投げます。

ここでは、throwsの特徴やそれぞれの違いを解説します。

throwsとは

throwsは、プログラムに例外が生じた際に、呼び出し元に例外処理を投げられる方法です。

例外処理を記述する場合、呼び出し元にthrowsで例外処理を投げる、または、try-catch構文を使うかのどちらかを使用します。

try-catch構文を使用する場合は、メソッドを使う場所で例外処理を実装可能です。

throwsを使用する場合は、呼び出し元に処理を投げるため、呼び出し元の処理内容によってはプログラム全体の処理を停止させることもあります。

一方、try-catch構文を使う場合は、例外処理を実施後にそれ以降の処理も実行されます。

try-catch構文については、以下の記事で詳しく解説していますので、参考までに。

【関連記事】

▶︎【Java】try-catch文の基本を解説!例外・エラー処理をマスターしよう【サンプルあり】

ここでは、throwsを使った例と、try-catch構文を使った例を確認してみます。

■throwsを使った記述例
import java.io.FileNotFoundException;
import java.io.FileReader;

public class Main {
    public static void main(String[] args) {
        String fileName = "sample.txt";
        try {
            throwsSample(fileName);
        } catch (FileNotFoundException e) {
            System.out.println(fileName + "を読み込みませんでした");
        }
        System.out.println("処理が終了しました");
    }
    public static void throwsSample(String fileName) throws FileNotFoundException {
        FileReader r = new FileReader(fileName);
        System.out.println(fileName + "を読み込みました");
    }
}
■実行結果
mbp:desktop potepan$ java Main
sample.txtを読み込みませんでした
処理が終了しました
■try-catch構文を使った記述例
import java.io.FileNotFoundException;
import java.io.FileReader;

public class Main {
    public static void main(String[] args) {
        String fileName = "sample.txt";
        try {
            FileReader r = new FileReader(fileName);
            System.out.println(fileName + "を読み込みました");
        } catch (FileNotFoundException e) {
            System.out.println(fileName + "を読み込みませんでした");
        }
        System.out.println("処理が終了しました");
    }
}
■実行結果
mbp:desktop potepan$ java Main
sample.txtを読み込みませんでした
処理が終了しました

throwsを複数使うには?

throwsは入れ子にして複数使うこともできます。

記述例は、次の通りです。

■記述例
import java.io.FileNotFoundException;
import java.io.FileReader;

public class Main {
    public static void main(String[] args) {
        String fileName = "sample.txt";
        try {
            throwsSampleFirst(fileName);
        } catch (FileNotFoundException e) {
            System.out.println(fileName + "を読み込みませんでした");
        }
        System.out.println("処理が終了しました");
    }
    public static void throwsSampleFirst(String fileName) throws FileNotFoundException {
        throwsSampleSecond(fileName);
    }
    public static void throwsSampleSecond(String fileName) throws FileNotFoundException {
        FileReader r = new FileReader(fileName);
        System.out.println(fileName + "を読み込みました");
    }
}
■実行結果
mbp:desktop potepan$ java Main
sample.txtを読み込みませんでした
処理が終了しました

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。