Java-接口上嵌套的可参数化类型的类型变量

时间:2018-10-19 18:22:59

标签: java generics

我有以下界面:

public interface Box<T> {
    T get();
}

我希望能够定义另一个以Box<SomeType>作为参数的接口,但是要让该接口“知道” SomeType是什么。

例如我想定义以下界面

// this doesn't compile
public interface BiggerBox<B extends Box<H>> {
    H get();
}

您可以做这样的想法:

BiggerBox<Box<String>> biggerBox = new SomeBiggerBox(new SomeBox("some string"));
String value = biggerBox.get();

我能找到的最接近的东西是:

public interface BiggerBox<B extends Box> {
    <U> U get();
}

但这没有编译时类型的安全性。

我认为这在Java中是不可能的,但是我想知道它是否完全可以(甚至通过疯狂的黑客攻击)。

编辑:我不想向接口添加第二个类型参数,即不添加BiggerBox<Box<String>, String>(这就是为什么我认为不可能的原因)

2 个答案:

答案 0 :(得分:2)

您需要将其添加为第二个类型参数:

public interface BiggerBox<B extends Box<H>, H> {
    H get();
}

答案 1 :(得分:1)

BiggerBox方法中没有使用“ B”的任何内容,因此没有必要在通用签名中使用它。 BiggerBox中也没有任何东西可以强迫“ get”来自Box实例,也没有任何东西可以迫使构造函数采用Box实例。

含义是BiggerBox应该简单地将“ get”委托给Box实例。

这是一个抽象类:

// Could also choose not to have it implement Box interface
public abstract class BiggerBox<T> implements Box<T> {

    private Box<T> box;

    public BiggerBox(Box<T> box) {
        this.box = box;
    }

    public T get() {
        return box.get();
    }
}

或作为界面:

// Could also choose not to have it extend Box interface
public interface BiggerBox<T> extends Box<T> {

    Box<T> getBox();

    default T get() {
        return getBox().get();
    }
}