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
的有效调用是什么样的?只是好奇而已。@XtremeBikerdoesntCompile(新的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> {}