本文介绍了< 和有什么不一样?扩展基础>和<T扩展基数>?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这个例子中:

import java.util.*;

public class Example {
    static void doesntCompile(Map<Integer, List<? 

doesntCompile() 编译失败:

Example.java:9: error: incompatible types: HashMap<Integer,List<Integer>> cannot be converted to Map<Integer,List<? 

compiles() 被编译器接受.

这个答案 解释了唯一的区别是与 <T 让你稍后引用类型,这似乎不是这种情况.

This answer explains that the only difference is that unlike <? , <T lets you reference the type later, which doesn't seem to be the case.

<有什么区别? 在这种情况下,为什么第一个不编译?

What is the difference between <? and <T in this case and why doesn't the first compile?

推荐答案

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

By defining the method with the following signature:

static <T 

并像这样调用它:

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

您正在将 T 与您提供的类型进行匹配.

you're matching T against the type you're providing.

在 jls §8.1.2 我们发现,(有趣的部分由我加粗):

In the jls §8.1.2 we find, that (interesting part bolded by me):

泛型类声明定义了一组参数化类型(第 4.5 节),通过类型参数对类型参数部分的每次可能调用都使用一个.所有这些参数化类型在运行时共享同一个类.

换句话说,类型 T 与输入类型匹配并分配了 Integer.签名将有效地变成 static void compiles(Map> map).

In other words, the type T is matched against the input type and assigned Integer. The signature will effectively become static void compiles(Map<Integer, List<Integer>> map).

当涉及到 doesntCompile 方法时,jls 定义了子类型化规则(§4.5.1,由我加粗):

When it comes to doesntCompile method, jls defines rules of subtyping (§4.5.1, bolded by me):

一个类型参数 T1 被称为包含另一个类型参数 T2,写作 T2 <= T1,如果 T2 表示的类型集在自反和传递闭包下可证明是 T1 表示的类型集的子集以下规则(其中 <: 表示子类型(第 4.10 节)):

  • ?扩展 T

  • ?

    ?扩展 T

    ?超级 T

    ? super T <= ? super S if S <: T

    ?超级 T

    ?超级 T

    ? super T <= ?

    T

    T

    T

    这意味着,那个? 确实包含 Integer 甚至 List 包含 List,但是 Map>Map>.可以在在此 SO 线程中找到有关该主题的更多信息.您仍然可以通过声明您期望 List<?扩展数>:

    This means, that ? indeed contains Integer or even List<? contains List<Integer>, but it's not the case for Map<Integer, List<? and Map<Integer, List<Integer>>. More on that topic can be found in this SO thread. You can still make the version with ? wildcard work by declaring, that you expect a subtype of List<? :

    public class Example {
        // now it compiles
        static void doesntCompile(Map<Integer, ? 

    这篇关于&lt; 和有什么不一样?扩展基础>和&lt;T扩展基数&gt;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-11 11:17