如何避免 return 参数中的(有界)通配符

How to avoid (bounded) wildcard in return parameter

我有一个接口,方法return使用有界通配符不可变集合。

public interface Foo {
    Set<? extends Bar> getAllBar();
}

public interface Bar {
    String getBar();
}

实现该接口的抽象 class 以及在不覆盖方法的情况下扩展它的几个具体 classes:

abstract class AbstractFoo implements Foo {
    public Set<? extends Bar> getAllBar() {
        return Collections.emptySet();
    }
}

以及扩展抽象 class 的具体 class,覆盖 getAllBar,缩小通配符:

public class FooImpl extends AbstractFoo {
    public Set<BarImpl> getAllBar() {
        return Collections.singleton(new BarImpl());
    }
}

public class BarImpl implements Bar {
    public String getBar() {
        return "Bar";
    }

    /**
     * additional BarImpl method
     */
    public boolean isWee() {
        return true;
    }
}

调用代码通常会迭代 returned 集合的项目作为 Bar,但是一些调用 classes,知道 FooImpl 期望 BarImpl 的集合能够调用 isWee().

class Zap {
    private FooImpl foo;

    boolean hasAnyWee() {
        return foo.getAllBar().stream().anyMatch(BarImpl::isWee);
    }
}

当然现在 SonarQube 抱怨 return 类型 (https://jira.sonarsource.com/browse/RSPEC-1452)

中的通配符

但我的情况就这么错了吗?

我怎样才能避免这种情况?

使界面本身通用:

public interface Foo<T extends Bar> {
    Set<T> getAllBar();
}

现在你可以拥有

public class EmptyFoo implements Foo<BarImpl> {
    public Set<BarImpl>() { return Collections.emptySet(); }
}