类型边界:传播具有多个边界的参数

Type bounds: Propagate parameter with multiple bounds

考虑以下(不变的)API:

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

现在我写了一个 class 接受一般的 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 class 中的 doFoo() 时遇到问题,因为当时不知道扩展 Foo 的确切类型和 实现Bar,所以我不能简单地将它转换为这样的类型。有没有办法在不更改 HolderFooBar 的接口的情况下解决这个问题?

您可以在引入正确类型转换的私有辅助方法中调用 doFoo

public void takeOverTheWorld() {
    if(this.foo instanceof Bar)
        doBarFoo();
}

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

如果您不介意该类型是 public 接口的一部分,您甚至可以在 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);
  }
}