类型边界:用多个边界传播参数



考虑以下(不可更改的)API:

interface Bar {}
class Foo {
    public static <T extends Foo & Bar> void doFoo(T param) {
         System.out.println("I shall be your ruler");
    }
}

现在我已经写了一个类,接受一般的Foo,但如果参数也是Bar,我想在一些方法中额外执行doFoo:

class Holder {
    public Holder(Foo foo) {
        this.foo = foo;
    }
    public void takeOverTheWorld() {
        if(this.foo instanceof Bar) {
            // Here I want to execute doFoo(), but I can't hand it over
            // because the bounds don't match
            // doFoo(this.foo);
        )
        // Enstablish my reign
    }
}

Holder使用示例:

class Yes extends Foo implements Bar {
}
// ------
Holder h = new Holder(new Yes());
h.takeOverTheWorld(); // Should print "I shall be your ruler"

正如在代码注释中提到的,我在Holder类中调用doFoo()有问题,因为当时没有确切的类型是已知的,扩展Foo 实现Bar,所以我不能简单地将其转换为这样的类型。在不改变Holder, FooBar的界面的情况下,有办法解决这个问题吗?

您可以在私有帮助器方法中调用doFoo,该方法为强制转换引入正确的类型:

public void takeOverTheWorld() {
    if(this.foo instanceof Bar)
        doBarFoo();
}
private <T extends Foo & Bar> void doBarFoo() {
    Foo.doFoo((T)this.foo);
}

如果你不介意该类型成为公共接口的一部分,你甚至可以在takeOverTheWorld中这样做:

public <T extends Foo & Bar> void takeOverTheWorld() {
    if(this.foo instanceof Bar)
        Foo.doFoo((T)this.foo);
}

创建Holder的泛型子类:

class SubHolder<T extends Foo & Bar> extends Holder {
  private T fooT;
  SubHolder(T foo) {
    super(foo);
    this.fooT = fooT;
  }
  @Override void takeOverTheWorld() {
    Foo.doFoo(fooT);
  }
}

最新更新