Java <;之间有什么区别;?扩展基础>;及<;T扩展基>;?

Java <;之间有什么区别;?扩展基础>;及<;T扩展基>;?,java,dictionary,generics,arraylist,jvm,Java,Dictionary,Generics,Arraylist,Jvm,在本例中: import java.util.*; public class Example { static void doesntCompile(Map<Integer, List<? extends Number>> map) {} static <T extends Number> void compiles(Map<Integer, List<T>> map) {} static void func

在本例中:

import java.util.*;

public class Example {
    static void doesntCompile(Map<Integer, List<? extends Number>> map) {}
    static <T extends Number> void compiles(Map<Integer, List<T>> map) {}

    static void function(List<? extends Number> outer)
    {
        doesntCompile(new HashMap<Integer, List<Integer>>());
        compiles(new HashMap<Integer, List<Integer>>());
    }
}
compiles()
被编译器接受

说明唯一的区别是与调用中的
不同:

compiles(new HashMap<Integer, List<Integer>>());

因此,显然,它不能接受
HashMap
作为参数。

通过定义具有以下签名的方法:

static <T extends Number> void compiles(Map<Integer, List<T>> map) {}

我建议你特别留意一下

坦率地说,你的方法并不复杂

static void doesntCompile(Map<Integer, List<? extends Number>> map) {}

staticvoiddoesntcompile(Map演示的简化示例。同样的示例可以可视化,如下所示

static void demo(List<Pair<? extends Number>> lst) {} // doesn't work
static void demo(List<? extends Pair<? extends Number>> lst) {} // works
demo(new ArrayList<Pair<Integer>()); // works
demo(new ArrayList<SubPair<Integer>()); // works for subtype too

public static class Pair<T> {}
public static class SubPair<T> extends Pair<T> {}

static void demo(列表)那么,对
doesntCompile
的有效调用是什么样的?只是好奇而已。@XtremeBiker
doesntCompile(新的HashMap@XtremeBiker,即使这样也可以,映射“不可从
HashMap
分配的”您能详细说明为什么它不能从中分配吗?此演示与
静态void演示(ListComments不用于扩展讨论;此对话一直是。[1]似乎在问同样的问题,但尽管它可能感兴趣,但实际上并不是重复的。[2]虽然这是一个很好的问题,但标题并没有正确反映最后一句中提出的具体问题。这里已经回答了这个问题。解释如何?[1]我想你的意思是
?扩展数字
,而不是
?扩展数字
[2]你的断言是:“这不是我们的情况List@You在这两种情况下,你都是对的。当谈到你的第二点时,我是以一种误导的方式写的。我的意思是
List@skomisa出于同样的原因,
List
不包含
List
。假设您有一个函数
静态无效检查(列表编号){}
。使用
检查调用时(new ArrayList());
它不编译,您必须将该方法定义为
静态无效检查(List@skomisa正如
Number
是列表的一个类型参数,您需要添加
?扩展
以使其协变,
ListOK。因为您提供了多级通配符(也称为“嵌套通配符”)的解决方案,并链接到相关JLS参考,获得赏金。为什么
@jaco0646不起作用?您基本上提出了与OP相同的问题,并且已被接受。请参见该答案中的代码示例。@skomisa,是的,我提出相同的问题有两个原因:一是这个答案实际上并不正确似乎解决了OP的问题;但第二个问题是,我发现这个答案更容易理解。我无法以任何方式理解Andronicus的答案,从而理解嵌套泛型与非嵌套泛型,甚至
T
vs
。问题的一部分是,当Andronicus到达其解释的关键点时,他遵从了另一个只使用琐碎示例的线程。我希望在这里得到更清晰、更完整的答案。@jaco0646好的。文档“Java泛型常见问题解答-类型参数”Angelika Langer有一个名为的FAQ。这是我所知道的解释OP问题中提出的问题的最佳来源。嵌套通配符的规则既不直接也不直观。
compiles(new HashMap<Integer, List<Integer>>());
public class Example {
    // now it compiles
    static void doesntCompile(Map<Integer, ? extends List<? extends Number>> map) {}
    static <T extends Number> void compiles(Map<Integer, List<T>> map) {}

    public static void main(String[] args) {
        doesntCompile(new HashMap<Integer, List<Integer>>());
        compiles(new HashMap<Integer, List<Integer>>());
    }
}
static void doesntCompile(Map<Integer, List<? extends Number>> map) {}
doesntCompile(new HashMap<Integer, List<Integer>>());
    static void doesntCompile(Map<Integer, List<? extends Number>> map) {
        List<Double> list = new ArrayList<>();
        list.add(0.);
        map.put(0, list);
    }
    static <T extends Number> void compiles(Map<Integer, List<T>> map) {
        List<Double> list = new ArrayList<>();
        list.add(10.);
        map.put(10, list); // does not compile
    }
static void demo(List<Pair<? extends Number>> lst) {} // doesn't work
static void demo(List<? extends Pair<? extends Number>> lst) {} // works
demo(new ArrayList<Pair<Integer>()); // works
demo(new ArrayList<SubPair<Integer>()); // works for subtype too

public static class Pair<T> {}
public static class SubPair<T> extends Pair<T> {}