キャストしないでサプタイプの型に変換する

ジェネリクスねた。
Java Generics and Collections: Speed Up the Java Development Process の9.4 Strategy に出てくる話です。

@Test
public void test() throws Exception {
    Aaa<Bbb> hoge = new Bbb();
    Bbb bbb = hoge.asSubtype();

    Aaa<Ccc> foo = new Ccc();
    Ccc ccc = foo.asSubtype();
}

interface Aaa<T extends Aaa<T>> {
    T asSubtype();
}

static class Bbb implements Aaa<Bbb> {
    public Bbb asSubtype() {
        return this;
    }
}

static class Ccc implements Aaa<Ccc> {
    public Ccc asSubtype() {
        return this;
    }
}

ポイントは

  • 再帰的な型パラメータを使う
  • サブタイプでthisを返す

本では、外部に公開するためというよりスーパータイプの中でサブタイプを知るために使っていますが、流れるようなインタフェースでも使えそうです。