Java例外を正しい方法で処理する方法

Java例外を正しい方法で処理する方法

プログラミング初心者として、 例外処理 頭を包むのは難しいかもしれません。コンセプト自体が難しいというわけではありませんが、用語によって、それが実際よりも進んでいるように見える場合があります。また、これは非常に強力な機能であるため、誤用や悪用されがちです。





この記事では、例外とは何か、例外が重要である理由、それらの使用方法、および避けるべき一般的な間違いについて学習します。最近のほとんどの言語にはある種の例外処理があるため、Javaから移行する場合は、これらのヒントのほとんどを持ち歩くことができます。





Java例外を理解する

Javaでは、 例外 アプリケーションの実行中に何か異常な(または「例外的な」)ことが発生したことを示すオブジェクトです。そのような例外は 投げられた 、これは基本的に例外オブジェクトが作成されることを意味します(エラーが「発生する」方法と同様)。





美しさはあなたができることです キャッチ スローされた例外。これにより、異常な状態に対処し、何も問題がなかったかのようにアプリケーションを実行し続けることができます。たとえば、Cのnullポインタはアプリケーションをクラッシュさせる可能性がありますが、Javaではスローしてキャッチできます

NullPointerException

■null変数がクラッシュを引き起こす可能性がある前。



例外は単なるオブジェクトですが、重要な特徴が1つあります。それは、

Exception

クラスまたはのサブクラス





Exception

。 Javaにはあらゆる種類の組み込み例外がありますが、必要に応じて独自の例外を作成することもできます。いくつかの 最も一般的なJavaの例外 含む:

  • NullPointerException
  • NumberFormatException
  • IllegalArgumentException
  • RuntimeException
  • IllegalStateException

では、例外をスローするとどうなりますか?





まず、Javaはimmediateメソッド内を調べて、スローした種類の例外を処理するコードがあるかどうかを確認します。ハンドラーが存在しない場合は、現在のメソッドを呼び出したメソッドを調べて、ハンドルが存在するかどうかを確認します。そうでない場合は、呼び出したメソッドを調べます それ メソッド、次に次のメソッドなど。 例外がキャッチされない場合、アプリケーションはスタックトレースを出力してからクラッシュします。 (実際には、単にクラッシュするよりも微妙な違いがありますが、それはこの記事の範囲を超えた高度なトピックです。)

スタックトレース 例外ハンドラを探している間にJavaがトラバースしたすべてのメソッドのリストです。スタックトレースは次のようになります。

Exception in thread 'main' java.lang.NullPointerException
at com.example.myproject.Book.getTitle(Book.java:16)
at com.example.myproject.Author.getBookTitles(Author.java:25)
at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

これから多くを集めることができます。まず、スローされた例外は

NullPointerException

。それはで発生しました

getTitle()

Book.javaの16行目のメソッド。そのメソッドはから呼び出されました

getBookTitles()

Author.javaの25行目。 それか メソッドはから呼び出されました

main()

Bootstrap.javaの14行目。ご覧のとおり、これらすべてを知っていると、デバッグが容易になります。

しかし、繰り返しになりますが、例外の真の利点は、例外をキャッチし、適切に設定し、クラッシュすることなくアプリケーションを再開することで、異常な状態を「処理」できることです。

コードでのJava例外の使用

あなたが持っているとしましょう

someMethod()

これは整数を受け取り、整数が0未満または100より大きい場合に破損する可能性のあるロジックを実行します。これは、例外をスローするのに適した場所である可能性があります。

Windows10の最初のこと
public void someMethod(int value) {
if (value 100) {
throw new
IllegalArgumentException

この例外をキャッチするには、どこに行く必要があります

someMethod()

と呼ばれ、使用します try-catchブロック

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
}
// ...
}

内のすべて 試す ブロックは、例外がスローされるまで順番に実行されます。例外がスローされるとすぐに、後続のすべてのステートメントがスキップされ、アプリケーションロジックはすぐににジャンプします。 キャッチ ブロック。

この例では、tryブロックに入り、すぐに呼び出します

someMethod()

。 200は0から100の間ではないので、

IllegalArgumentException

スローされます。これにより、の実行が直ちに終了します。

someMethod()

、tryブロックの残りのロジックをスキップします(

someOtherMethod()

呼び出されることはありません)、catchブロック内で実行を再開します。

電話した場合はどうなりますか

someMethod(50)

代わりは? NS

IllegalArgumentException

スローされることはありません。

someMethod()

通常どおり実行されます。 tryブロックは通常どおり実行され、

someOtherMethod()

someMethod()が完了したとき。いつ

someOtherMethod()

終了すると、catchブロックはスキップされ、

callingMethod()

継続します。

tryブロックごとに複数のcatchブロックを持つことができることに注意してください。

public void callingMethod() {
try {
someMethod(200);
someOtherMethod();
} catch (IllegalArgumentException e) {
// handle the exception in here
} catch (NullPointerException e) {
// handle the exception in here
}
// ...
}

オプションであることに注意してください ついに ブロックも存在します:

public void method() {
try {
// ...
} catch (Exception e) {
// ...
} finally {
// ...
}
}

finishブロック内のコードは いつも 何があっても実行されます。 tryブロックにreturnステートメントがある場合、finallyブロックは、メソッドから戻る前に実行されます。 catchブロックで別の例外をスローすると、例外がスローされる前にfinallyブロックが実行されます。

メソッドが終了する前にクリーンアップする必要があるオブジェクトがある場合は、finallyブロックを使用する必要があります。たとえば、tryブロックでファイルを開き、後で例外をスローした場合、finallyブロックを使用すると、メソッドを終了する前にファイルを閉じることができます。

catchブロックなしでfinallyブロックを持つことができることに注意してください:

public void method() {
try {
// ...
} finally {
// ...
}
}

これにより、スローされた例外がメソッド呼び出しスタックを伝播できるようにしながら、必要なクリーンアップを実行できます(つまり、ここで例外を処理したくないが、最初にクリーンアップする必要があります)。

Javaでのチェックされた例外とチェックされていない例外

ほとんどの言語とは異なり、Javaは チェックされた例外未チェックの例外 (たとえば、C#にはチェックされていない例外のみがあります)。チェックされた例外 しなければならない 例外がスローされるメソッドでキャッチされます。そうしないと、コードがコンパイルされません。

チェックされた例外を作成するには、

Exception

。未チェックの例外を作成するには、

RuntimeException

チェックされた例外をスローするメソッドは、メソッドシグネチャでこれを示す必要があります。 投げる キーワード。 Javaが組み込まれているので

IOException

チェックされた例外である場合、次のコードはコンパイルされません。

public void wontCompile() {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

最初に、チェックされた例外をスローすることを宣言する必要があります。

public void willCompile() throws IOException {
// ...
if (someCondition) {
throw new IOException();
}
// ...
}

メソッドは例外をスローするものとして宣言できますが、実際には例外をスローしないことに注意してください。それでも、例外をキャッチする必要があります。そうしないと、コードがコンパイルされません。

チェックされた例外またはチェックされていない例外をいつ使用する必要がありますか?

公式のJavaドキュメントには この質問のページ 。これは、簡潔な経験則で違いを要約します。 'クライアントが例外からの回復を合理的に期待できる場合は、それをチェック済みの例外にします。クライアントが例外から回復するために何もできない場合は、チェックされていない例外にします。

ただし、このガイドラインは古くなっている可能性があります。一方では、チェックされた例外はより堅牢なコードになります。一方、Javaと同じ方法で例外をチェックした言語は他にありません。これは、2つのことを示しています。1つは、他の言語がそれを盗むのに十分な機能ではないこと、2つは、例外がなくても絶対に生きることができることです。さらに、チェックされた例外は、Java8で導入されたラムダ式ではうまく機能しません。

Java例外の使用に関するガイドライン

例外は便利ですが、簡単に誤用されたり悪用されたりします。ここでは、混乱を避けるためのヒントとベストプラクティスをいくつか紹介します。

  • 一般的な例外よりも特定の例外を優先します。 NumberFormatExceptionを使用します以上IllegalArgumentException可能であれば、それ以外の場合はIllegalArgumentExceptionを使用します以上RuntimeException可能であれば。
  • 絶対に捕まえないThrowable Exceptionクラスは実際にはThrowableを拡張します、およびcatchブロックは実際にはThrowableで機能しますまたはThrowableを拡張する任意のクラス。ただし、Errorクラスも拡張しますThrowable 、そしてあなたは決してErrorを捕まえたくありませんなぜならError ■重大な回復不能な問題を示します。
  • 絶対に捕まえないException InterruptedException拡張Exception 、したがって、ExceptionをキャッチするすべてのブロックInterruptedExceptionもキャッチします、これは非常に重要な例外であり、何をしているのかを理解していない限り、(特にマルチスレッドアプリケーションで)混乱させたくないものです。代わりにどの例外をキャッチするかわからない場合は、何もキャッチしないことを検討してください。
  • 説明メッセージを使用して、デバッグを容易にします。 例外をスローするときは、Stringを指定できます。引数としてのメッセージ。このメッセージには、Exception.getMessage()を使用してcatchブロックでアクセスできます。メソッドですが、例外がキャッチされない場合、メッセージはスタックトレースの一部としても表示されます。
  • 例外をキャッチして無視しないようにしてください。 チェックされた例外の不便さを回避するために、多くの初心者や怠惰なプログラマーはキャッチブロックを設定しますが、それは空のままにします。悪い!常に適切に処理しますが、それができない場合は、少なくともスタックトレースを出力して、例外がスローされたことを確認します。 Exception.printStackTrace()を使用してこれを行うことができます方法。
  • 例外の使いすぎに注意してください。 あなたがハンマーを持っているとき、すべてが釘のように見えます。例外について最初に知ったとき、すべてを例外に変える義務があると感じるかもしれません...アプリケーションの制御フローのほとんどが例外処理に帰着するところまで。例外は「例外的な」発生を対象としていることを忘れないでください。

これで、例外が何であるか、それらが使用される理由、およびそれらを独自のコードに組み込む方法を理解するのに十分快適であるはずです。コンセプトを完全に理解していなくても大丈夫です!頭の中で「カチッ」と音がするのに少し時間がかかったので、急いでいる必要はありません。ゆっくりしてください。

質問がありますか?私が見逃した他の例外関連のヒントを知っていますか?以下のコメントでそれらを共有してください!

共有 共有 つぶやき Eメール プロジェクトのデータを視覚化するためのデータフロー図を作成する方法

プロセスのデータフロー図(DFD)は、データがソースから宛先にどのように流れるかを理解するのに役立ちます。作成方法は次のとおりです。

次を読む
関連トピック
  • プログラミング
  • Java
著者について ジョエル・リー(1524の記事が公開されました)

Joel Leeは、2018年からMakeUseOfの編集長を務めています。彼は理学士号を取得しています。コンピュータサイエンスの分野で、9年以上のプロの執筆および編集の経験。

Windows10用のWindowsXPゲーム
JoelLeeのその他の作品

ニュースレターを購読する

ニュースレターに参加して、技術的なヒント、レビュー、無料の電子書籍、限定セールを入手してください。

購読するにはここをクリックしてください