小编典典

和之间有什么区别?

java

在此示例中:

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>>());
    }
}

doesntCompile() 无法编译为:

Example.java:9: error: incompatible types: HashMap<Integer,List<Integer>> cannot be converted to Map<Integer,List<? extends Number>>
        doesntCompile(new HashMap<Integer, List<Integer>>());
                      ^

compiles()被编译器接受。

这个答案说明唯一的区别是,与不同<? ...>,它<T...>允许您稍后引用类型,似乎并非如此。

是什么区别<? extends Number>,并<T extends Number>在这种情况下,为什么不第一编译?


阅读 268

收藏
2020-12-03

共1个答案

小编典典

通过使用以下签名定义方法:

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

并像这样调用它:

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

jls§8.1.2中,我们发现(有趣的部分被我加粗了):

通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型 。所有这些参数化类型在运行时共享同一类。

换句话说,将类型T与输入类型进行匹配并进行分配Integer。签名将有效地变为static void compiles(Map<Integer, List<Integer>> map)

关于doesntCompile方法,jls定义了子类型化规则(第4.5.1节,由我加粗):

如果在以下规则的自反和传递闭包中,证明T2表示的类型集是T1表示的类型集的子集,则类型自变量T1包含另一个类型自变量T2,写为T2 <=
T1。其中<:表示子类型(§4.10)):

  • ?扩展T <=?如果T <:S则扩展S

  • ?扩展T <=?

  • ?超级T <=?如果S <:T则为超级S

  • ?超级T <=?

  • ?超级T <=?扩展对象

  • T <= T

  • T <=?延伸T

  • T <=?超级T

这意味着,? extends Number确实包含Integer,甚至List<? extends Number>包含List<Integer>,但Map<Integer, List<? extends Number>>and
并非如此Map<Integer,List<Integer>>。在该SO线程中可以找到有关该主题的更多信息。您仍然可以?通过声明期望使用以下子类型来使带有通配符的版本起作用List<? extends Number>

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>>());
    }
}
2020-12-03