Javaのthrowとthrowsの違いは、throwは例外を実際に投げる文、throwsは例外が外へ出る可能性を宣言する句という点です。
名前が似ているため最初は混ざりやすいですが、置かれる場所も役割も違います。throwはメソッドの中で使い、throwsはメソッド定義の横に書きます。

『その場で起こすのが throw』『外へ伝える可能性を示すのが throws』と覚えると、かなり整理しやすくなります。
この記事では、両者の違い、具体的なコード、try-catchとの関係、checked exceptionでthrowsが必要になる理由まで順番に解説します。
この記事はtry-catch文そのものの入門ではなく、try-catchの次に混ざりやすいthrowとthrowsの読み分けに絞ります。try-catchの基本はJavaの例外処理の基本、リソース解放の話はtry-with-resourcesの記事に分けます。
まず結論:throwは投げる、throwsは宣言する
Java Language Specificationでは、throwは例外を発生させて制御を移す文として定義されています。一方、throwsはメソッドやコンストラクタが外へ出し得るchecked exceptionを宣言する句です。
次の図では、『実行される文』と『宣言として書く句』を分けて見てください。

1分で違いを見る
| 比較 | throw | throws |
|---|---|---|
| 書く場所 | メソッド本体の中 | メソッド宣言やコンストラクタ宣言 |
| 役割 | 例外を実際に投げる | 例外が外へ出る可能性を示す |
| 例 | throw new IllegalArgumentException() | read() throws IOException |
| try-catchとの関係 | 投げた先で捕まる | 呼び出し側に処理を促す |
throwはどこで使うか
入力値が不正なときなど、メソッドの中で自分から例外を発生させたい場合にthrowを使います。
static void validatePrice(int price) {
if (price < 0) {
throw new IllegalArgumentException("price must be zero or more");
}
}
この例では、価格が負数ならその場で処理を止め、IllegalArgumentExceptionを投げています。
throwsはどこで使うか
メソッドの中でchecked exceptionが外へ出る可能性がある場合、呼び出し側へその可能性を知らせるためにthrowsを書きます。
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
static String loadText(Path path) throws IOException {
return Files.readString(path);
}
この例では、ファイル読み込み中にIOExceptionが起きる可能性を、メソッド宣言で示しています。
throwsを書いたからといって、その場で例外が処理されるわけではありません。呼び出し側がtry-catchで処理するか、さらに外へ渡す必要があります。
try-catchとどうつながるか
public static void main(String[] args) {
try {
String text = loadText(Path.of("memo.txt"));
System.out.println(text);
} catch (IOException e) {
System.out.println("ファイルを読めませんでした");
}
}
ここでは、loadText側がthrows IOExceptionで可能性を示し、呼び出し側がtry-catchで受け止めています。
try-catchそのものの基本が曖昧な場合は、先にJavaの例外処理の基本を読んでから戻ると理解しやすいです。
checked exceptionでthrowsが必要になる理由
checked exceptionは、コンパイラが『処理するか、外へ渡すかを決めてください』と確認する種類の例外です。そのため、メソッド内で発生し得るchecked exceptionを自分で捕まえない場合は、throwsで宣言する必要があります。
一方、IllegalArgumentExceptionのような実行時例外は、必ずしもthrowsへ書く必要はありません。ここが最初につまずきやすい分岐です。
初心者がつまずきやすいポイント
| つまずき | まずこう理解する |
|---|---|
throwsを書けば処理済みだと思う | throwsは宣言であり、処理ではない |
throwとthrowsを同じ場所で使うと思う | throwは本体、throwsは宣言部 |
| 実行時例外でも必ずthrowsが必要だと思う | unchecked exceptionでは必須ではない |
| caller側の処理を見ない | 例外は投げた後の受け取り方まで見る |
リソースを開く処理と例外の関係まで進みたい場合は、try-with-resourcesも次に読むとつながります。
throwsをさらに外へ渡す場合
呼び出し側で必ずcatchしなければならない、というわけではありません。今のメソッドでは処理せず、さらに外側へ任せたい場合は、呼び出し側のメソッドにもthrowsを書きます。
static void printFile(Path path) throws IOException {
String text = loadText(path);
System.out.println(text);
}
このコードでは、printFileの中ではIOExceptionを処理していません。代わりに、printFileを呼び出す側へ『IOExceptionが外へ出るかもしれない』と伝えています。
つまりthrowsは、例外を消すためのものではありません。責任の場所を外へ渡すための宣言です。最終的には、どこかでtry-catchするか、さらに外へ伝えるかを決める必要があります。
例外メッセージは読む人のために書く
throwで例外を投げるときは、メッセージも大切です。後からログを見た人が、何が悪かったのかを判断できるようにします。
if (price < 0) {
throw new IllegalArgumentException("price must be zero or more: " + price);
}
この例では、単に『エラー』と書くのではなく、どの値が問題だったのかまで含めています。初心者のうちは、例外メッセージを利用者向けの文章ではなく、開発者が原因を追うための手がかりとして考えるとよいです。
よくある疑問
throwsだけを書けば例外は解決する?
解決したわけではありません。throwsは『このメソッドでは処理せず、外へ伝える』という宣言です。呼び出し側がtry-catchで受けるか、さらに外へthrowsで渡すかを決める必要があります。
throw new Exception() と書けばよい?
何でもExceptionで投げると、呼び出し側が原因を判断しにくくなります。入力値が不正ならIllegalArgumentExceptionのように、状況に合う例外クラスを選ぶ方が読みやすくなります。初心者のうちは、まず既存の代表的な例外を使い分けるところから始めましょう。
RuntimeExceptionはthrowsに書かないの?
RuntimeException系の例外は、必ずthrowsへ書く必要はありません。ただし、APIとして利用者に注意してほしい場合に、ドキュメント上で説明することはあります。まずは『checked exceptionは処理か宣言が必要、unchecked exceptionは必須ではない』という大枠を押さえれば十分です。
公式情報と関連して読みたい記事
- Java Language Specification: The throw Statement
- Java Language Specification: Method Throws
- Oracle Java Tutorials: How to Throw Exceptions
- Javaの例外処理の基本
- NullPointerExceptionの基礎
- Java学習ロードマップ完全版
まとめ
throwとthrowsは、名前は似ていますが役割が違います。
この違いを押さえると、例外処理のコードを『どこで起きて、どこで受けるのか』まで追いやすくなります。
