java - Java 中的泛型和通配符使用静态函数 - "not applicable for the arguments"错误

标签 java generics wildcard

我无法弄清楚以下代码有什么问题,具体来说,为什么不是 <A extends ClassA>相当于<? extends ClassA> .

不应该bar()可以调用foo()

编译器说方法 foo(...) 不适用于参数 (...)
(确切的错误在下面的评论中指定)

static class ClassA {};
static class ClassB<A extends ClassA> {};

private static <A extends ClassA> Collection<ClassB<A>> foo(Collection<ClassB<A>> as) {
    return as;
}

private Collection<ClassB<? extends ClassA>> bar(Collection<ClassB<? extends ClassA>> as) {
    // Error:
    // The method foo(Collection<ClassB<A>>) is not applicable 
    // for the arguments (Collection<ClassB<? extends ClassA>>)
    return foo(as);
}

谢谢!

最佳答案

问题是您正在尝试传递 Collection<ClassB<? extends ClassA>> 类型的内容变成某种类型的东西 Collection<ClassB<A>> .它们不兼容。

为了使两个泛型类型兼容,它们的类型参数(如果两者都不是通配符)必须完全匹配。这里,类型参数是ClassB<? extends ClassA>ClassB<A> (对于某些 A );两者都不是通配符,而且它们永远不可能完全相同——无论如何A也就是说,它代表一种特定的类型。确实ClassB<A> (无论 A 是什么)将是 ClassB<? extends ClassA>子类型 ;但这无关紧要——就像String一样是 Object 的子类型但是Collection<String>Collection<Object>不兼容。

如果你制作foo()稍微更通用一些,这样通用参数就在顶层:

private static <T extends ClassB<? extends ClassA>> Collection<T> foo(Collection<T> as) {
    return as;
}

然后您可以使用捕获来执行此操作:

private Collection<? extends ClassB<? extends ClassA>> bar(Collection<? extends ClassB<? extends ClassA>> as) {
    return foo(as);
}

关于java - Java 中的泛型和通配符使用静态函数 - "not applicable for the arguments"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12077313/

相关文章:

java - JSON 响应中的 @type

java - 方法产量如何工作?

java - Java中的引用变量有大小吗?

java - 如何使用 Gson API 处理 JSON 变量中的正斜杠

java - 在 python 代码中解码 Java int 数组——找到了适合我的情况的解决方法

Func 上的 C# 可选参数丢失泛型类型推断

java - 为什么在 Java 泛型中需要通配符?

java - 通配符和一个实现两个接口(interface)的类的问题

php - 在 codeigniter 路由中使用通配符?

filter - 在 LDAP 搜索过滤器/查询中使用通配符