Javaのジェネリクスでハマった件について

抽象基底クラスにcompareToメソッドの実装を持たせた以下のような
クラス定義を行った場合にHogeListHolderがコンパイルエラーとなります。
原因はHogeクラスはComparableEntityの継承クラスではなく
ComparableHogeの継承クラスと判断されるからです。


・HogeListHolderがコンパイルエラーになったケース

public interface ComparableEntity<T> extends Comparable<T>

/* compareToメソッドの実装を持つ */
public abstract class ComparableHoge
       implements ComparableEntity<ComparableHoge>

public class Hoge extends ComparableHoge

/* compareToメソッドの実装を持つ */
public abstract class ListHolder<T extends ComparableEntity<T>>
       implements Comparable<T>

/* 型の不一致でコンパイルエラー */
public class HogeListHolder extends ListHolder<Hoge>


以下のようにComparableHogeにも型パラメーターを追加すれば
HogeListHolderの型にHogeが指定できるようになります。
型の判定が厳密になったので抽象クラスを導入する場合は注意が必要ですね。
継承ではなく、interfaceを駆使しろとの思し召しですかね・・・。


・修正版

public interface ComparableEntity<T> extends Comparable<T>

/* 型パラメーターを追加 */
public abstract class ComparableHoge<T extends ComparableHoge<T>>
       implements ComparableEntity<T>

/* 型パラメーターを指定する */
public class Hoge extends ComparableHoge<Hoge>

public abstract class ListHolder<T extends ComparableEntity<T>>
       implements Comparable<T>

/* コンパイルが通る */
public class HogeListHolder extends ListHolder<Hoge>