Java / 基礎 / ジェネリクス / 再帰的ジェネリクス

Java / 基礎 / ジェネリクス / 再帰的ジェネリクス

再帰型境界というやつ。

実装する自分自身の型を使って何かしたいと思いつつ、型情報を外部からうけとって確定させたいという要望を満たしたい場合に用いられる。

このようなモノは共変状態にしたい場合によく用いられる。

public class Hoge<T extends Piyo> {}

自分自身を格納できる Box というクラスを作ってみる

public class Box {
    private Box b1;
    public Box getB1() {
        return b1;
    }
    public void setB1(Box b1) {
        this.b1 = b1;
    }
}
Box box1 = new Box();
Box box2 = new Box();
box1.setB1(box2);		

ではここに数値と文字列のどっちでも取れる value を格納できるようにする。

public class Box<T> {
    private Box<T> b1;
    private T v;
 
    public Box<T> getB1() {
        return b1;
    }
 
    public void setB1(Box<T> b1) {
        this.b1 = b1;
    }
    public void setV(T v) {
        this.v = v;
    }
}

ではこいつを継承して String 専用の StringBox を作りたい。

となるのだが、ここで b1 の取り扱いに問題が出てくる、返したり受けたりしたいのは Box<String> ではなくて StringBox なのである。

となると、こうなるのである。

外から型は取りたいのだがその型情報自体がそもそも必要なので自身の定義に自身の定義を書いてその中で型を定義(確定ではない)している。

public class Box<T, E extends Box<T, E>> {
    private E b1;
    private T v;
 
    public E getB1() {
        return b1;
    }
 
    public void setB1(E b1) {
        this.b1 = b1;
    }
    public void setV(T v) {
        this.v = v;
    }
}

となると StringBox はこのように確定される、自身を入れているが、継承関係により型情報を注入しており、それがさらに継承の条件に使われるという再帰構造になっている。

public class StringBox extends Box<String, StringBox> {
}
java/basic/generics/recursive.txt · 最終更新: 2022-06-15 17:35 by ore