What are multi-level wild cards? Confusion in syntax
generics, java, wildcard
Solution
Can someone elaborate on these three quotes with example. I am totally lost into the syntax
Well, it wouldn't make sense to write those 3 quotes again here, as I can't give a better explanation than that. Instead, I will try to answer your other questions below, then possibly you will understand the answer to this one too. If not, you can ask your query again and I'll try to elaborate a little further.
Document says, para-1 is the concrete instantiation of a generic type and other is not the concrete instantiation? How is that?
A concrete instantiation is the one in which all the type arguments are concrete types, and are known at compile time. For e.g., `List<String>` is a concrete instantiation, because `String` is a concrete type. Its type is known at compile time. Whereas, `List<? extends Number>` is not a concrete type, because `? extends Number` can be any type that extends `Number`. So, its type is unknown at compile time. Similarly, `Map<String, Integer>` is a concrete instantiation of generic type `Map<K, V>`.
In the case of multi-level type parameters, `List<List<? extends Number>>`, the outer `List` is a concrete instantiation of `List<E>`, because the type of elements is known to be a `List` at compile time, although the inner `List` is a wildcard instantiation, as the type of elements stored can be `Integer`, `Double`, any subclass of `Number`. But that paragraph is talking about the outer type only. And the outer type can only contain `List` type.
That's why the first paragraph said, it's a heterogenous collection of `Pair`, because the actual type parameter of `Pair` can be anything, but that is certain to be `Pair` and nothing else.
What does it mean to read the wild-cards top down?
Talking in layman's term, it means from left-to-right. While determining the type of the parameterized type, you first see the outermost type parameter. Then if that type parameter is itself a parameterized type, then you move onto the type parameters of that parameterized type. So, we read the type parameters, from left-to-right.
What is the advantage of multi-level wild cards?
Suppose you want to create a List of List of Fruits. Now your inner `List` can contain any kind of of fruits. An apple is also a fruit, and a banana is also a fruit. So, you have to make sure that you get all of them. Now, since generic types are invariant, in the sense, `List<Apple>` is not the same as `List<Fruit>`, you can't add a `List<Apple>` if your type of list is `List<List<Fruit>>`. For that you would need to use `wildcards` like this - `List<List<? extends Fruit>>`, which can now take `List<Apple>`, `List<Banana>`, list of any fruit.
Problem
I am reading multi-level wild cards from AngelikaLangerGenericsFaq. I am pretty confused about the syntax. The document says The type `Collection<Pair<String,?>>` is a concrete instantiation of the generic Collection interface. It is a heterogenous collection of pairs of different types. It can contain elements of type `Pair<String,Long>` , `Pair<String,Date>` , `Pair<String,Object>` , `Pair<String,String>` , and so on and so forth. In other words, `Collection<Pair<String,?>>` contains a mix of pairs of different types of the form `Pair<String,?>` . The type `Collection<? extends Pair<String,?>>` is a wildcard parameterized type; it does NOT stand for a concrete parameterized type. It stands for a representative from the family of collections that are instantiations of the Collection interface, where the type argument is of the form `Pair<String,?>` . Compatible instantiations are `Collection<Pair<String,Long>>` , `Collection<Pair<String,String>>` , `Collection<Pair<String,Object>>` , or `Collection<Pair<String,?>>` . In other words, we do not know which instantiation of Collection it stands for. As a rule of thumb, you have to read multi-level wildcards top-down. I am confused about the following points. - Can someone elaborate on these three quotes with example. I am totally lost into the syntax - Document says, para-1 is the concrete instantiation of a generic type and other is not the concrete instantiation? How is that? - What does it mean to read the wild-cards top down? - What is the advantage of multi-level wild cards? Can someone elaborate these points. Thanks.