У меня есть интерфейс с методом, возвращающим коллекцию 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)
Но так ли это неправильно в моем случае?
Как можно избежать этого?