Java
 Computer >> コンピューター >  >> プログラミング >> Java

Javaで例外をスローするメソッドをオーバーライドする際に守るべきルールとは?

メソッドオーバーライド時の例外に関する基本ルール

Javaでは、例外をスローするメソッドをオーバーライドする際に、いくつかの重要なルールに従う必要があります。親クラス(スーパークラス)と子クラス(サブクラス)の間でthrows句の扱いを誤るとコンパイルエラーが発生するため、以下のルールをしっかり理解しておきましょう。

ルール1:親クラスのメソッドが例外をスローしない場合

親クラスのメソッドが例外を一切スローしない場合、子クラスでオーバーライドしたメソッドはチェック例外(検査例外)をスローできません。ただし、非チェック例外(非検査例外)であれば自由にスローすることが可能です。

class Parent {
    void doSomething() {
      // ...
    }
}
class Child extends Parent {
    void doSomething() throws IllegalArgumentException {
      // ...
    }
}

ルール2:親クラスのメソッドがチェック例外をスローする場合

親クラスのメソッドが1つ以上のチェック例外をスローする場合、子クラスのメソッドは親と同じチェック例外、そのサブクラス、あるいはより狭い範囲のチェック例外をスローできます。さらに、任意の非チェック例外をスローすることも許容されます。

class Parent {
    void doSomething() throws IOException, ParseException {
      // ...
    }
    void doSomethingElse() throws IOException {
      // ...
    }
}
class Child extends Parent {
    void doSomething() throws IOException {
      // ...
    }
    void doSomethingElse() throws FileNotFoundException, EOFException {
      // ...
    }
}

ルール3:親クラスのメソッドが非チェック例外をスローする場合

親クラスのメソッドのthrows句に非チェック例外が含まれている場合、子クラスのメソッドは非チェック例外を1つもスローしなくてもよく、また、互いに無関係な例外であっても任意の数の非チェック例外をスローすることができます。

class Parent {
    void doSomething() throws IllegalArgumentException {
      // ...
    }
}
class Child extends Parent {
    void doSomething() throws ArithmeticException, BufferOverflowException {
      // ...
    }
}

サンプルコード

以下に、実際のオーバーライドの例を示します。親クラスのtest()メソッドはIOExceptionをスローする可能性を宣言していますが、子クラスでオーバーライドされたメソッドは例外をスローしません。これはルールに沿った正しい実装です。

import java.io.*;
class SuperClassTest{
    public void test() throws IOException {
        System.out.println("SuperClassTest.test() method");
    }
}
class SubClassTest extends SuperClassTest {
    public void test() {
        System.out.println("SubClassTest.test() method");
    }
}
public class OverridingExceptionTest {
    public static void main(String[] args) {
        SuperClassTest sct = new SubClassTest();
        try {
            sct.test();
        } catch(IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

実行結果

SubClassTest.test() method

このように、子クラスのメソッドが親クラスより広い範囲のチェック例外を宣言しない限り、ポリモーフィズムを利用した呼び出しでも例外処理が正しく機能します。オーバーライド時のthrows句は、必ず親クラスの宣言と同等かそれより狭い範囲に抑えることを心がけましょう。

  1. Javaのpaint()メソッドとrepaint()メソッドの違いをわかりやすく解説

    JavaでGUIアプリケーションを開発する際、コンポーネントの描画に関わるpaint()メソッドとrepaint()メソッドは、役割がまったく異なる重要なメソッドです。この記事では、両者の違いと正しい使い方を具体例とともに解説します。 paint()メソッドとrepaint()メソッドの違い paint()メソッドとは paint()は、コンポーネントを実際に描画するための処理(描画命令)を記述するメソッドです。Java AWTでは、このメソッドをオーバーライドして独自の描画処理を実装します。 一方、Java SwingではpaintComponent()メソッドをオーバーライドするのが推奨さ

  2. Javaメソッドのオーバーライドのルールを徹底解説

    Javaにおいて、メソッドを適切にオーバーライドするためには、いくつかの重要なルールを守る必要があります。この記事では、オーバーライドを行う際に考慮すべきルールを項目別に整理し、わかりやすく解説します。 オーバーライドの基本ルール 引数リストは、オーバーライド対象のメソッドと完全に同一である必要があります。 戻り値の型は、スーパークラスで宣言された元のメソッドの戻り値の型と同じであるか、そのサブタイプ(共変戻り値)である必要があります。 インスタンスメソッドは、サブクラスに継承されている場合にのみオーバーライドできます。継承されていないメソッドはオーバーライドできません。 コンストラクタは