CodeGym /Java Blog /ランダム /例外: チェック済み、チェックなし、およびカスタム
John Squirrels
レベル 41
San Francisco

例外: チェック済み、チェックなし、およびカスタム

ランダム グループに公開済み
やあ!前回のレッスンでは、Java 言語の例外について理解し、それらを処理する方法の例を見ました。今日は例外の構造を詳しく見て、独自の例外を記述する方法を学びます :)

例外の種類

前に述べたように、Java には例外が多数あり、その数は約 400 です。ただし、それらはすべてグループに分けられているため、覚えるのはかなり簡単です。これはどのように見えるかです。 例外: チェック済み、チェックなし、カスタム - 2 すべての例外はクラス内に共通の祖先を持っていますThrowableそこから、例外 ( Exception ) とエラー ( Error ) という 2 つの主要なグループが派生します。エラー- これは、Java 仮想マシンの操作に関連する重大な実行時エラーを表します。ほとんどの場合、エラーはコード内の重大な欠陥を示しているため、処理する必要はありません。これらの中で最も有名なものは、StackOverflowError (これは、たとえば、メソッドがそれ自体を無限に呼び出す場合に発生します) とOutOfMemoryErrorです。(これは、新しいオブジェクトを作成するのに十分なメモリがない場合に発生します)。ご覧のとおり、このような状況では、通常、実行時に処理することはまったくありません。コードが単に間違って書かれているだけであり、再加工する必要があります。 例外- これは例外を表します。つまり、プログラムの実行中に発生する例外的で計画外の状況です。これらはエラーほど深刻ではありませんが、それでも注意が必要です。すべての例外は、 selectedunchecked の2 つのタイプに分類されます。 例外: チェック済み、チェックなし、カスタム - 3 すべてのチェック例外はExceptionクラスから派生します。「チェック済み」とはどういう意味ですか? これについては、前回のレッスンで触れました。 「したがって、Java コンパイラは、最も一般的な例外と、それらが発生する可能性のある状況を知っています。」 たとえば、コードがファイルからデータを読み取る場合、そのファイルが存在しない可能性が高いことがわかります。そして、そのような状況はたくさんあります(それは推測できます)。したがって、コンパイラは、コードにこれらの潜在的な例外が存在するかどうかを事前にチェックします。それらが見つかった場合、それらを処理するか再ス​​ローするまで、コードはコンパイルされません。2 番目のタイプの例外は「未チェック」です。それらはクラスから派生しますRuntimeException。チェック例外とどう違うのですか? から派生したクラスもたくさんあるようですRuntimeException(実行時例外について説明します)。違いは、コンパイラーがこれらのエラーを予期しないことです。「コードを書いたときは何も怪しいところはなかったのですが、実行中に何か問題が発生しました。どうやらコードに誤りがあるようです!」と言っているようです。そして実際、これは真実です。チェックされない例外は、ほとんどの場合、プログラマーのエラーの結果として発生します。 そして、コンパイラは、人々が自らの手で作り出す可能性のあるすべての悪い状況を予測できるわけではないことは明らかです。:) したがって、そのような例外がコードで処理されるかどうかはチェックされません。すでにいくつかの未チェックの例外が発生しています。
  • ゼロ除算時にArithmeticException が発生する
  • 配列の外側の位置にアクセスしようとすると、ArrayIndexOutOfBoundsExceptionが発生します。
もちろん、Java の作成者が必須の例外処理を導入することもできたと想像できますが、その場合はコードが複雑すぎます。除算演算の場合、try-catch誤ってゼロで除算してしまっていないかどうかをチェックするためにブロックを作成する必要がありますか? try-catch配列にアクセスするたびに、インデックスが範囲外にあるかどうかをチェックするブロックを作成する必要があります。すべてがスパゲッティコードになってしまい、まったく読めなくなってしまうので、この考えが放棄されたのも当然です。try-catchその結果、チェックされていない例外をブロックで処理したり再スローしたり する必要はありません(ただし、これはエラーの場合と同様に技術的には可能です)。

独自の例外をスローする方法

もちろん、Java の作成者は、プログラム内で発生する可能性のある例外的な状況をすべて予測することはできません。世界にはあまりにも多くのプログラムがあり、あまりにも多様です。ただし、必要に応じて独自の例外を作成できるため、これは心配する必要はありません。これはとても簡単です。あなたがしなければならないのは、独自のクラスを作成することだけです。その名前が「Exception」で終わることを確認してください。コンパイラはこれを必要としませんが、コードを読む他のプログラマは、それが例外クラスであることをすぐに理解します。さらに、クラスがExceptionクラスから継承されていることを示します (コンパイラーはこれを必要とします)。たとえば、Dogクラスがあるとします。を使って犬の散歩ができますwalk()方法。しかし、その前に、ペットが首輪、リード、口輪を付けているかどうかを確認する必要があります。このギアのいずれかが不足している場合は、独自の例外DogIsNotReadyExceptionをスローします。そのコードは次のようになります。

public class DogIsNotReadyException extends Exception {

   public DogIsNotReadyException(String message) {
       super(message);
   }
}
クラスが例外であることを示すには、クラス名の後に「 extends Exception 」と記述する必要があります (これは、「クラスが Exception クラスから派生している」ことを意味します)。コンストラクターでは、Exception文字列メッセージを使用してクラス コンストラクターを呼び出すだけです (例外が発生した場合は、エラーの説明であるメッセージがユーザーに表示されます)。これがクラスコードでどのように見えるかは次のとおりです。

public class Dog {

   String name;
   boolean isCollarPutOn;
   boolean isLeashPutOn;
   boolean isMuzzlePutOn;


   public Dog(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

   }

   public void putCollar() {

       System.out.println("The collar is on!");
       this.isCollarPutOn = true;
   }

   public void putLeash() {

       System.out.println("The leash is on!");
       this.isLeashPutOn = true;
   }

   public void putMuzzle() {
       System.out.println("The muzzle is on!");
       this.isMuzzlePutOn = true;
   }

   public void walk() throws DogIsNotReadyException {

   System.out.println("We're getting ready for a walk!");
   if (isCollarPutOn && isLeashPutOn && isMuzzlePutOn) {
       System.out.println("Hooray, let's go for a walk! " + name + " is very happy!");
   } else {
       throw new DogIsNotReadyException(name + " is not ready for a walk! Check the gear!");
   }
 }

}
ここで、メソッドはDogIsNotReadyExceptionwalk()をスローします。 これはキーワード throw を使用して行われます。前に述べたように、例外はオブジェクトです。したがって、メソッド内で例外が発生した場合 (犬に何かが欠けている場合)、新しいオブジェクトを作成し、キーワード throw を使用してそれをスローします。メソッド宣言に「throws DogIsNotReadyException 」を追加します。言い換えれば、コンパイラは、メソッドの呼び出しが例外的な状況になる可能性があることを認識します。したがって、プログラム内のどこかでこのメソッドを呼び出す場合は、この例外を処理する必要があります。これをメソッドで実行してみましょう。 DogIsNotReadyExceptionwalk()main()

public static void main(String[] args) {
  
   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   dog.walk();// Unhandled exception: DogIsNotReadyException
}
これではコンパイルできません。例外は処理されません。try-catch例外を処理するために コードをブロックでラップします。

public static void main(String[] args) {

   Dog dog = new Dog("Buddy");
   dog.putCollar();
   dog.putMuzzle();
   try {
       dog.walk();
   } catch (DogIsNotReadyException e) {
       System.out.println(e.getMessage());
       System.out.println("Checking the gear! Is the collar on? " + dog.isCollarPutOn + "\r\n Is the leash on? "
       + dog.isLeashPutOn + "\r\n Is the muzzle on? " + dog.isMuzzlePutOn);
   }
}
次に、コンソール出力を見てみましょう。 首輪はオンです! 銃口がついてる!散歩の準備中です!バディは散歩の準備ができていません! ギアをチェックしてみよう!ギアチェック中!首輪はついていますか?true リードはついていますか?false 銃口は付いていますか?true コンソール出力がどれほど有益であるかを見てください。私たちはプログラムで実行されるすべてのステップを確認します。どこでエラーが発生したかがわかり、犬に何が欠けているのかもすぐにわかります。:) そして、それが独自の例外を作成する方法です。ご覧のとおり、何も複雑なことはありません。Java の作成者は、装備が不十分な犬に対する特別な例外をわざわざ言語に含めなかったにもかかわらず、私たちは彼らの見落としを修正しました。:)
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION