Javaのdynamic type checking

よく知られていることだったかもしれないのですが、そうだったっけと思ったのでメモです。Java言語の場合、type checkingはコンパイル時に終わっていると思っていました。

import java.util.HashSet;
import java.util.LinkedHashSet;

public class TypeTest {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        LinkedHashSet linkedHashSet = (LinkedHashSet)hashSet;
    }
}

これは、コンパイルエラーになりません。が、実行するとLinkedHashSetにキャストする(downcasting)ところでjava.lang.ClassCastExceptionが発生します。継承ツリーの中にあるクラスどうしのキャストは"動くかもしれない"のでコンパイルエラーにならないということのようです。継承ツリーの中に無いクラスへのキャストはコンパイルエラーになるので、このようなケースが必ずしもdynamic type checkingではないのですが、状況によってはdynamicにtype checkingが完了する場合があったのですね、Javaは。