如何在返回参数中避免(有界)通配符

时间:2018-11-23 08:26:59

标签: java return-type bounded-wildcard

我有一个接口,该接口的方法返回带有有限通配符的 immutable 集合。

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

public interface Bar {
    String getBar();
}

实现该接口的抽象类以及一些扩展该类而不覆盖该方法的具体类:

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

还有一个扩展抽象类的具体类,它覆盖了 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;
    }
}

调用代码通常会以Bar的形式迭代返回的集合的项目,但是一些知道FooImpl的调用类希望BarImpl的集合能够调用 isWee()

class Zap {
    private FooImpl foo;

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

当然,现在SonarQube抱怨返回类型(https://jira.sonarsource.com/browse/RSPEC-1452)中的通配符

但是就我而言,这太错了吗?

我怎么可能避免这种情况?

1 个答案:

答案 0 :(得分:2)

使接口本身具有通用性:

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

现在您可以拥有

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