[英]Subclass not matching generic wildcard capture
我有以下示例類表示我遇到的情況:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
class Scratch {
interface CompletablePredicate<T> extends Function<T, CompletionStage<Boolean>> {
}
interface AttributeProvider{}
interface IDProvider extends AttributeProvider {
String getID();
}
interface TypeProvider extends AttributeProvider {
String getType();
}
static class Event implements IDProvider, TypeProvider{
@Override
public String getID() {
return "123";
}
@Override
public String getType() {
return "foo";
}
}
static class IDFilter implements CompletablePredicate<IDProvider> {
@Override
public CompletionStage<Boolean> apply(IDProvider idProvider) {
String id = idProvider.getID();
boolean res = id.equals("123");
return CompletableFuture.completedFuture(res);
}
}
static class TypeFilter implements CompletablePredicate<TypeProvider> {
@Override
public CompletionStage<Boolean> apply(TypeProvider typeProvider) {
String type = typeProvider.getType();
boolean res = type.equals("foo");
return CompletableFuture.completedFuture(res);
}
}
public static void main(String[] args) {
List<CompletablePredicate<? extends AttributeProvider>> filters = new ArrayList<>();
filters.add(new IDFilter());
filters.add(new TypeFilter());
Event event = new Event();
filters.stream().forEach(f -> f.apply(event)); <- failing here
}
}
正如所強調的,它無法在f.apply(event)
編譯並出現錯誤:
Error:(40, 47) incompatible types: Scratch.Event cannot be converted to capture#1 of
? extends Scratch.AttributeProvider
我認為 Event 是 AttributeProvider 類型,因此它應該匹配“?擴展 AttributeProvider”。
這個錯誤的原因是什么?
在這種情況下不能使用通配符。 您需要確切地知道列表中的對象類型,以便插入並再次將其取出。
您可以選擇: List<CompletablePredicate<IDProvider>> filters = new ArrayList<>();
或者在這種情況下: List<IDFilter> filters = new ArrayList<>();
OP 添加更多信息后編輯。 我想出了以下解決方案。 我刪除了 CompletablePredicate 形式的類型參數,而是給了它一個supports
方法。 這個想法是這個方法檢查參數是否是正確的類型。 然后,在將事件應用於列表中的所有項目之前,我首先過濾該列表,因此我確定所有剩余元素都支持它。
interface CompletablePredicate extends Function<AttributeProvider, CompletionStage<Boolean>> {
boolean supports(AttributeProvider provider);
}
interface AttributeProvider { }
interface IDProvider extends AttributeProvider {
String getID();
}
interface TypeProvider extends AttributeProvider {
String getType();
}
static class Event implements IDProvider, TypeProvider {
@Override
public String getID() {
return "123";
}
@Override
public String getType() {
return "foo";
}
}
static class IDFilter implements CompletablePredicate {
@Override
public boolean supports(AttributeProvider provider) {
return provider instanceof IDProvider;
}
@Override
public CompletionStage<Boolean> apply(AttributeProvider idProvider) {
String id = ((IDProvider) idProvider).getID();
boolean res = id.equals("123");
return CompletableFuture.completedFuture(res);
}
}
static class TypeFilter implements CompletablePredicate {
@Override
public boolean supports(AttributeProvider provider) {
return provider instanceof TypeProvider;
}
@Override
public CompletionStage<Boolean> apply(AttributeProvider typeProvider) {
String type = ((TypeProvider) typeProvider).getType();
boolean res = type.equals("foo");
return CompletableFuture.completedFuture(res);
}
}
public static void main(String[] args) {
List<CompletablePredicate> filters = new ArrayList<>();
filters.add(new IDFilter());
filters.add(new TypeFilter());
Event event = new Event();
filters.stream()
.filter(f -> f.supports(event))
.forEach(f -> f.apply(event));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.