凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 47023
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

先日ジェネリクスで引っ掛かった点をメモ。

自己言及するジェネリクスで述べたような具象型に具象型自身の型を扱わせることをもくろんだ型を作った場合の話。

public class GenericsTest {
  static abstract class S<T extends S<T>> {}

  static class extends S<A> {}
  static class extends {}
  static class extends S<A> {}

  static class X1<T extends S<T>>{}
  static class X2<T extends S<?>>{}
  static class X3<T extends S<? super T>>{}

  public static void main(String[] args) {
    X1<A> x1A; // OK
    X1<B> x1B; // NG
    X1<C> x1C; // NG

    X2<A> x2A; // OK
    X2<B> x2B; // OK
    X2<C> x2C; // OK

    X3<A> x3A; // OK
    X3<B> x3B; // OK
    X3<C> x3C; // NG
  }
}

Sが親となるクラスで<T extends S<T>>という境界をもつジェネリクス型変数Tを持ちます。 サブクラスであるAはこのTにA自身を渡すことで、Sクラス中にT型で宣言した部分をA型にすることができるのですね。

そのA型を継承したクラスBを考えた場合、BはS<A>を継承しているのでB extends S<A>ということになります。 なのでX1の境界<T extends S<T>>に合致しません。

こうした型を受け入れれるように規制を緩めたのがX2で<T extends S<?>>としています。 この場合、穴ができてCのようなAのサブクラスでもないのにSの型変数TにAを渡したような歪なクラスを宣言した場合に許容されてしまいます(x2C部分)。 クラスS中に表現されるTを具象型自身にするという趣旨からすればこのような歪な型は許容したくありません。 T型の戻り値のメソッドでreturn this;とか書きたいわけです。

なので正確に型を表現するとしたならば<T extends S<? super T>>とします。 これでAはもちろん、AのサブクラスであるBも許容され、歪なCは弾くことができます。

投稿日時 : 2009年1月23日 23:45
コメント
タイトル
名前
Url
コメント