Search code examples
javagenericswildcardjlsunbounded-wildcard

Java language specification on wildcards


I am going through this link (Chapter 4. Types, Values, and Variables) and did not understand below point:

The relationship of wildcards to established type theory is an interesting one, which we briefly allude to here. Wildcards are a restricted form of existential types. Given a generic type declaration G<T extends B>, G<?> is roughly analogous to Some X <: B. G<X>.

I appreciate if you provide good example to understand above point clearly.

Thanks in advance.


Solution

  • The wording and formatting of this statement are a bit unlucky*. The link in the answer by Maouven actually covers the general topic pretty well, but one can try to focus on the particular case of Java and Wildcards here:

    Wildcards are a restricted form of existential types. Given a generic type declaration G, G is roughly analogous to Some X <: B. G.

    This basically says that the type parameter of the G is any subtype of B. And this is always the case, even when you don't say it explicitly.

    Consider the following snippet, which hopefully illustrates the point:

    class B { } 
    class G<T extends B> 
    {
        T get() { return null; }
    }
    
    public class Example
    {
        public static void main(String[] args)
        {
            G<?> g = null;
    
            // This works, even though "G<?>" seemingly does not say 
            // anything about the type parameter:
            B b = g.get();
        }
    }
    

    The object that you obtain by calling g.get() is of type B, because the declaration of G<T extends B> guarantees that any type parameter (even if it is the ? wildcard) always be "at least" of type B.

    (In contrast to that: If the declaration only was G<T>, then the type obtained from g.get() would only be of type Object)


    The relationship is described as "roughly analogous" to the type theoretic notation. You can probably imagine this as saying: If the declaration is G<T extends B>, and you use the type G<?>, then this roughly (!) means: There exists a type X extends B, and the ? here stands for this (unknown) type X.


    An aside: Note that this also refers to Insersection Types. If you declared the class as class G<T extends B & Runnable>, then the statements

    B b = g.get();
    Runnable x = g.get();
    

    would both be valid.


    * The "unlucky" formatting referred to the fact that the source code of this paragraph actually reads

        ... is roughly analogous to <span class="type">Some <span class="type">X</span> ...
    

    making clearer that the word "Some" already is part of the type that is being defined there formally...