Javaのコンパイラは宣言された型情報のみを頼りにコンパイルを行う。
よって、A型にA型のサブクラスであるB型を代入するような場合でも、
メソッドの定義などはA型に定義されたものとして判断する。
もちろんオーバーライドによって実行時に実体に応じた挙動は実現できるのだが、
あくまで型判断は宣言したものとして行う。よってB型の定義なら問題なくても、A型として使用する際に問題があれば、コンパイルエラーになる。
具体的にはメソッドの例外の定義。
下記のコードのようにA型で例外をスローするメソッドをオーバーライドで例外をスローしないようにしても、4行目でA型として宣言している以上、5行目でtry-catch文を記述しないとコンパイルエラーになる。
public class Main { public static void main(String[] args) { A b = new B(); b.hello(); } } class A { public void hello() throws Exception { throw new Exception(); } } class B extends A { public void hello() { System.out.println("B"); } }