What is the difference between <? extends Base> and ?

前端 未结 4 1539
温柔的废话
温柔的废话 2021-02-01 03:24

In this example:

import java.util.*;

public class Example {
    static void doesntCompile(Map> map) {}
    static &l         


        
4条回答
  •  时光说笑
    2021-02-01 04:30

    By defining the method with the following signature:

    static  void compiles(Map> map) {}
    

    and invoking it like:

    compiles(new HashMap>());
    

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

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

    A generic class declaration defines a set of parameterized types (§4.5), one for each possible invocation of the type parameter section by type arguments. All of these parameterized types share the same class at run time.

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

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

    A type argument T1 is said to contain another type argument T2, written T2 <= T1, if the set of types denoted by T2 is provably a subset of the set of types denoted by T1 under the reflexive and transitive closure of the following rules (where <: denotes subtyping (§4.10)):

    • ? extends T <= ? extends S if T <: S

    • ? extends T <= ?

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

    • ? super T <= ?

    • ? super T <= ? extends Object

    • T <= T

    • T <= ? extends T

    • T <= ? super T

    This means, that ? extends Number indeed contains Integer or even List contains List, but it's not the case for Map> and Map>. 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> map) {}
        static  void compiles(Map> map) {}
    
        public static void main(String[] args) {
            doesntCompile(new HashMap>());
            compiles(new HashMap>());
        }
    }
    

提交回复
热议问题