如何避免 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(); }
}
我有一个接口,方法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(); }
}