Java

【Java】例外とポリモフィズム

こんにちは、ともです。

今回は、Javaでの例外とポリモフィズムについて理解をまとめておきたいと思います。

例外をうまくcatchできない場合、ポリモフィズムを理解すると問題を解決することができます。

到達不可能なcatch

次のプログラムではSubSampleExceptionで例外をcatchすることはできません。

eclipseでコードを書いた場合は、エラーが出ます。

class SampleException extends Exception{}
class SubSampleException extends SampleException{}

public class Main {
	public static void main(String[] args) {
		try {
			sample();
			sub();
		} catch(SampleException se) {
			
		} catch(SubSampleException sse) {
			
		}
	}
	
	public static void sample() throws SampleException {
		throw new SampleException();
	}
	
	public static void sub() throws SubSampleException {
		throw new SubSampleException();
	}
}

SubSampleExceptionで補足されることはないためエラーが出ます。

Exception in thread “main” java.lang.Error: Unresolved compilation problem:

Unreachable catch block for SubSampleException. It is already handled by the catch block for SampleException

at try_catch_01.Main.main(Main.java:10)

これはポリモフィズムが関係しています。

次にポリモフィズムとは何か見ていきましょう。

ポリモフィズム

例のプログラムではSubSampleExceptionはSampleExceptionを継承しています。

継承にある場合、親の型で子のインスタンスを受け取ることができます。

次の例では、SampleException(親)の型でSubSampleException(子)のインスタンを格納できています。

class SampleException extends Exception{}
class SubSampleException extends SampleException{}

public class Main {
	public static void main(String[] args) {
		SampleException se = new SubSampleException();
	}

}

ポリモフィズムとは、多態性・多相性・多様性など言われ、各要素が複数の型に属することを許す性質のことを指します。

反対語は、モノモフィズムで、各要素は1つの型に格納される性質のことです。

ポリモフィズムと例外との関係について見ていきましょう。

ポリモフィズムと例外

public class Main {
	public static void main(String[] args) {
		try {
			sample();
			sub();
		} catch(SampleException se) {
			
		} catch(SubSampleException sse) {
			
		}
	}
	
	public static void sample() throws SampleException {
		throw new SampleException();
	}
	
	public static void sub() throws SubSampleException {
		throw new SubSampleException();
	}
}

sampleメソッドはSampleExceptionクラスのインスタンスをthrowしていますね。

これを格納できる型がcatchブロックにあれば例外を補足します。

// SampleExceptionの型を代入可能
// SubSampleExceptionの型を代入可能
catch(SampleException se) {
			
} 
// SubSampleExceptionの型を代入可能
catch(SubSampleException sse) {
			
}

ポリモフィズムにより、SampleExceptionの型では

  • SampleExceptionクラス
  • SubSampleExcepitonクラス

の2つのインスタンスを格納することができます。

つまり、

// SubSampleExceptionの型を代入可能
catch(SubSampleException sse) {
			
}

このブロックで例外をキャッチする前に、SampleExceptionでキャッチできてしまうため、SubSampleExceptionのキャッチブロックで例外を補足することはありません。

到達不可能なコードとなります。

エラーを解決するには

例外を投げる順番を変える必要があります。

サブクラスから順番に記述するようにしましょう。

public static void main(String[] args) {
		try {
			sample();
			sub();
		} catch(SubSampleException sse) {
			
		} catch(SampleException se) {
			
		}
}

まとめ

ポリモフィズムと例外について理解をまとめました。

ポリモフィズムというと難しく聞こえるかもしれませんが、親クラスならサブクラスのインスタンスを受け取ることができるんだな、と覚えておけば良いです。(少し挙動が変わりますが、大まかな理解から覚えていましょう!)