复杂类型的通用通配符bounderies

时间:2016-06-01 10:30:46

标签: java generics

我不明白generic wildcard bounderies ussage 你可以解释为什么processList工作得很好而processMap在下面的例子中失败并出现编译错误?我应该如何更改processMap的签名,使其适用于Map<String, List<String>>Map<String, List<Object>>

public void processList(List<? extends Object> list) {
}

public void processMap(Map<String, List<? extends Object>> map) {
}

public void f() {
    List<String> list = new ArrayList<>();
    Map<String, List<String>> map = new HashMap<>();

    processList(list); // OK
    processMap(map); // ERROR
}

将泛型类型定义从方法参数类型移动到方法参数时,制作了技巧

public void processMap(Map<String, List<? extends Object>> map)
public <T extends Object> void processMap(Map<String, List<T>> map)

我现在想知道两者之间的区别。已移至another thread

3 个答案:

答案 0 :(得分:1)

如果删除通配符,可以使其正常工作。即您创建一个具有命名类型的通用函数:<T extends Object>

public <T extends Object> void processMap(Map<String, List<T>> map) {
}

public void processList(List<? extends Object> list) {
}

public void f() {
    List<String> list = new ArrayList<>();
    Map<String, List<String>> map = new HashMap<>();

    processList(list); // OK
    processMap(map); // OK now
    processMap(new HashMap<String, List<Integer>>()); // this is OK too
}

不幸的是,我无法解释为什么使用通配符的函数不起作用。

答案 1 :(得分:1)

半答案:以下代码为我编译。

缺失:对命名T的工作原理有一个很好的解释;但一个未命名的?没有。

public <T> void processMap(Map<String, List<T>> map) {
}

public void f() {
    Map<String, List<String>> map = new HashMap<>();
    processMap(map);
    Map<String, List<Object>> map2 = new HashMap<>();
    processMap(map2);
}

答案 2 :(得分:0)

Map<String, List<? extends Object>> map = new HashMap<>();

在f()方法中进行上述更改并且它可以正常工作。 Java编译器检查变量的类型,所以两者都应该相同,我可能错了。