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

Javaのメソッドオーバーライド:サブクラスは例外をスローしない選択ができるのか?

Javaでは、スーパークラスのメソッドが特定の例外をスローするように宣言されている場合でも、サブクラスでそのメソッドをオーバーライドする際に、例外を一切スローしないことが可能です。これはJavaのオーバーライドにおける重要なルールの一つです。

オーバーライド時の例外に関するルール

スーパークラスのメソッドがチェック例外(検査例外)をスローする場合、サブクラスのオーバーライドメソッドは次のいずれかを選択できます。

  • 例外をまったくスローしない
  • スーパークラスと同じ例外をスローする
  • スーパークラスがスローする例外のサブクラス(より具体的な例外)をスローする

ただし注意点として、スーパークラスがスローする例外よりも広範囲な(親の)例外をスローすることはできません。例えば、スーパークラスが FileNotFoundException をスローする場合、サブクラスで IOException をスローするとコンパイルエラーになります。

コード例

以下の例では、スーパークラスの sampleMethod() メソッドは FileNotFoundException 例外をスローするよう宣言されています。一方、サブクラスでオーバーライドされた sampleMethod() メソッドは、まったく例外をスローしていません。

それにもかかわらず、このプログラムはエラーなく正常にコンパイルされ、実行されます。

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Scanner;

abstract class Super {
    public void sampleMethod() throws FileNotFoundException {
        System.out.println("Method of superclass");
    }
}

public class ExceptionsExample extends Super {
    @Override
    public void sampleMethod() {
        System.out.println("Method of Subclass");
    }

    public static void main(String args[]) {
        ExceptionsExample obj = new ExceptionsExample();
        obj.sampleMethod();
    }
}

実行結果

Method of Subclass

解説

この動作が許される理由は、ポリモーフィズム(多態性)にあります。スーパークラス型の変数を通じてメソッドを呼び出す場合、呼び出し元はスーパークラスのメソッド宣言に基づいて例外処理を行います。サブクラス側で例外をスローしない実装にしても、呼び出し元が想定する契約(例外処理の範囲)を満たしているため、問題なく動作するのです。

逆に、サブクラスでより広い例外や新しいチェック例外をスローするようにすると、スーパークラスを利用していた既存のコードがその例外に対応できなくなる可能性があるため、Javaのコンパイラはこれを禁止しています。

  1. JavaのSwingUtilities.invokeLater()メソッドの使い方を徹底解説

    invokeLater()メソッドとはinvokeLater()メソッドは、SwingUtilitiesクラスが提供するstaticメソッドの一つで、AWTイベントディスパッチスレッド(Event Dispatch Thread)上でタスクを非同期に実行するために使用されます。このメソッドはSwingUtilities.invokeAndWait()とよく似た動作をしますが、大きな違いは、処理のリクエストをイベントキューに登録した後、すぐに呼び出し元へ制御を返すという点です。つまり、invokeLater()は引数で渡されたRunnableオブジェクト内のコードブロックの実行完了を待ちません。

  2. JavaでJPanelのpaintComponent()メソッドを実装する方法をわかりやすく解説

    JPanelはJavaにおける軽量コンテナであり、それ自体は不可視(インビジブル)なコンポーネントとして扱われます。デフォルトのレイアウトにはFlowLayoutが採用されています。JPanelを生成した後は、Containerクラスから継承されたadd()メソッドを呼び出すことで、ボタンやラベルなどの他のコンポーネントをJPanelオブジェクトに自由に追加できます。 paintComponent()メソッドとは このメソッドは、単なる背景色の描画にとどまらず、JPanel上に独自の図形や画像などを描画したい場合に必要となります。paintComponent()メソッドはすでにJPanelクラ