java - 无法使用通配符编译相关的 Java 泛型参数

标签 java generics nested-generics

由于不明确的推理,以下 Java 小示例无法编译:

package genericsissue;

import java.util.ArrayList;
import java.util.List;

interface Attribute<V> {}

interface ListAttribute extends Attribute<List<?>> {}

public class Context {
    public <T, A extends Attribute<T>> void put(Class<A> attribute, T value) {
        // implementation does not matter for the issue
    }

    public static void main(String[] args) {
        Context ctx = new Context();
        List<?> list = new ArrayList<String>();
        ctx.put(ListAttribute.class, list);
    }
}

带有 ctx.put 的行产生以下错误:

Context.java:18: <T,A>put(java.lang.Class<A>,T) in genericsissue.Context cannot be applied to (java.lang.Class<genericsissue.ListAttribute>,java.util.List<capture#35 of ?>)

如果不使用通配符,属性模式可以正常工作。

有没有解释为什么编译器不接受带有通配符类型的值?

最佳答案

问题是,list 的参数类型不是真的List<?> .编译器首先执行“通配符捕获”以将其类型转换为 List<x> for some x .通常这会提供更多信息和帮助。但不是你的情况。它驱动类型推断认为 T=List<x> ,但是 ListAttribute不扩展 Attribute<List<x>>

您可以提供明确的类型参数来解决它

ctx.<List<?>, ListAttribute>put(ListAttribute.class, list);
      (T)      (A)

关于java - 无法使用通配符编译相关的 Java 泛型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16613194/

相关文章:

generics - Rust DRY特性和泛型-Impl Add和Mul几乎相同

java - 使用 Function<T, 将 Integer 传递给泛型方法时出现编译错误?扩展号码>>

java - Java 中的级联泛型类型声明

c# - 为什么不能推断出嵌套的泛型类型?

java - 使用两个数组创建一副牌

java - 生成终端读取其标准输入

java - Android - setVisibility 不改变 RelativeLayout 的可见性

java - 如何用Java制作一个图 block

c# - WCF 通用字典和理解 WCF

Java8 类型通用删除方法签名和 lambda 不起作用