无法分配接收通用列表和 returns 列表<?> 的方法返回的结果

Unable to assign the result returned by the Method that receives a generic List and returns a List<?>

我正在尝试过滤实现接口的对象列表。我正在尝试为所有 类.

创建一个通用方法

类似于:

interface SomeInterface {
    String getFlag();
}


class SomeObject implements SomeInterface {
    public String getFlag() {
        return "X";
    }
}


List<SomeObject> someObjectList = new ArrayList<>();

// Compilation error here
List<SomeObject> filterList = filterGenericList(someObjectList, "X");


private List<?> filterGenericList(List<? extends SomeInterface> objects, String flag) {
        return objects.stream()
                .filter(it -> it.getFlag().equals(flag))
                .collect(Collectors.toList());
}

如何运行远离编译错误?

 Incompatible types. 
 Found: 'java.util.List<capture<?>>', 
 Required: 'java.util.List<SomeObject>'

当您 return List<?> 时,这意味着方法 return 是某种未知类型的列表。 Java 不知道它是与输入列表相同类型的列表。为此,创建一个通用类型 T 并将输入和输出列表都设置为 List<T>.

private <T extends SomeInterface> List<T> filterGenericList(List<T> objects, String flag) {
    return objects.stream()
        .filter(it -> it.getFlag().equals(flag))
        .collect(Collectors.toList());
}

Unbounded wildcard <?> 也称为 未知类型 是一种告诉编译器无法预测泛型类型的方法,因此编译器将不允许将 未知类型的列表 分配给 SomeObject 的列表,因为无法确保此分配是安全的。

如果您有一个属于不同 classes 实现 SomeInterface 的对象列表,以便区分它们,您可以显式传递目标实例 class Class<T> 作为参数进入方法。

您似乎正试图通过使用方法 getFlag() 重新发明相同的机制。它看起来不可靠,因为没有什么可以阻止你打错字或意外地在两个不同的 class 中实现 getFlag(),从而使它 return 具有相同的值。

private <T extends SomeInterface> List<T> filterGenericList(List<? extends SomeInterface> objects, 
                                                            Class<T> targetClass) {
    return objects.stream()
        .filter(it -> targetClass.isAssignableFrom(it.getClass()))
        .map(targetClass::cast)
        .collect(Collectors.toList());
}

首先,List 没有任何类型信息。您期望一个 SomeObject 列表,但您的方法只是 returns 任何类型的列表。

为了实现您的目标,您应该将过滤方法定义为

private static  <T extends SomeInterface> List<T> filterGenericList(List<T> objects, String flag)

通过这种方式,您可以保证返回的列表与输入列表的类型相同