java.util.ServiceLoaderでDIできる?

この本http://g-ec2.images-amazon.com/images/I/51eDoWWRrEL._SS500_.jpgをいただいたので読んでいたのですが、java.util.ServiceLoaderについて語られているところがあったので、このクラスについて調べてみました。このクラスはJDK1.6以降でしか使えないのでNetBeansでは同等の機能があるクラスを定義してそちらを使っているようですが、この方式を dependency injectionと呼ぶことにしていると書いてありました。厳密にはDIではないかもしれないけれど、injectingされるスロットを作っているところから、DIと呼ぶことにしたそうです。
APIドキュメントServiceLoader (Java Platform SE 6)に説明があるように、META-INF/servicesディレクトリ以下にサービスタイプのfully-qualified binary nameと同じ名前をファイルを作って、そこにサービスプロバイダのクラス名(実際にインスタンス化して使うクラスの名前)を書いておくという使いかたをします。JDK1.6のjava.util.spiやjava.text.spiパッケージにこの方法で利用できるプロバイダクラスがいくつかあります。これといったコンフィギュレーションをしなくても使えるお手軽DI(もどき)とのことです。
ServiceLoaderについては「Java SE 6完全攻略」第11回 コンポーネントのロードを行うServiceLoader | 日経 xTECH(クロステック)http://www.javaspecialists.eu/archive/Issue139.htmlに詳しい説明がありました。

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は。