So I read through the main Java Generic FAQ and the single thing which is holding me up are nested wildcards with lower bounds. I want to give you an example of what I do understand, something specifically which works and how I view it. Maybe you could tell me the way I am thinking about this is wrong even though the compiler isn't complaining in the "good" case.
Example 1 (makes sense):
static void WildcardsMethod(List<? extends Pair<? extends Number>> list)
{
System.out.println("It worked");
}
static void TestWildcardsMethod()
{
List<Pair<Integer>> list = null;
WildcardsMethod(list);
}
I first look at the deepest wildcard and bound in WildcardMethod's signature. It is looking for Pair<? extends Number>
. Therefore, I could use Pair<Integer>
, Pair<Double>
and so on. Now I have something which looks like the below code in my mind if I decided to substitute Pair<Integer>
for Pair<? extends Number>
:
List<? extends Pair<Integer>>
Now, the wildcard represents a type/subtype of the parametrized type Pair<Integer>
. Therefore, I can either pass a Pair<Integer>
or SubPair<Integer>
to WildcardsMethod.
Example 2 (makes sense):
static void WildcardsMethod(List<? extends Pair<? super Number>> list)
{
System.out.println("It worked");
}
static void TestWildcardsMethod()
{
List<Pair<Number>> list = null;
WildcardsMethod(list);
}
I look and see that I first need a Pair<? super Number>
so I decide to pass in Pair<Number>
resulting in the following code:
? extends Pair<Number>
I then look at the leftmost wildcard and see that I can use either Pair<Number>
or SubPair<Number>
. I end up passing List<Pair<Number>>
.
So in other words, I see the deepest wildcard as asking for a subtype or supertype of the innermost bound (Number). I then go to the top level wildcard and look for a subtype/supertype of the generic type (Pair).
Example 3 (doesn't make sense):
static void WildcardsMethod(List<? super Pair<? super Number>> list)
{
System.out.println("It worked");
}
static void TestWildcardsMethod()
{
List<Pair<Object>> list = null;
WildcardsMethod(list);
}
Well, in terms of Pair<? super Number>
, Object is definitely a supertype of Number so Pair<Object>
should work just as it did for the previous examples. The following is what I think of when trying to understand this:
? super Pair<Object>
So I am limited to either Pair<Object>
or SuperPair<Object>
. However, none of this works.
Example 4 (doesn't make sense):
static void WildcardsMethod(List<? super Pair<? extends Number>> list)
{
System.out.println("It worked");
}
static void TestWildcardsMethod()
{
List<Pair<Integer>> list = null;
WildcardsMethod(list);
}
It's the same thing here. Pair<Integer>
belongs to the family of Pair<? extends Number>
resulting in the following:
? super Pair<Integer>
I can then pass in either Pair<Integer>
or SuperPair<Integer>
However, this too does not work.
So I am either thinking of this wrong and somehow that model works for extends but not for super or I am simply missing something about lowerbounds and nested wildcards.