3

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.

Darketh
  • 33
  • 3

1 Answers1

0

Example 1:

  1. Is List<Pair<Integer>> a subtype of List<? extends Pair<? extends Number>>?
  2. It would be if Pair<Integer> is a subtype of Pair<? extends Number>. Is it?
  3. Yes, because Integer is a subtype of Number.

Example 2:

  1. Is List<Pair<Number>> a subtype of List<? extends Pair<? super Number>>?
  2. It would be if Pair<Number> is a subtype of Pair<? super Number>. Is it?
  3. Yes, because Number is a supertype of Number.

Example 3:

  1. Is List<Pair<Object>> a subtype of List<? super Pair<? super Number>>?
  2. It would be if Pair<Object> is a supertype of Pair<? super Number>. Is it?
  3. No, it is not. A parameterized type with a specific parameter can never be a supertype of a parameterized type with a wildcard.

Example 4:

  1. Is List<Pair<Integer>> a subtype of List<? super Pair<? extends Number>>?
  2. It would be if Pair<Integer> is a supertype of Pair<? extends Number>. Is it?
  3. No, it is not. A parameterized type with a specific parameter can never be a supertype of a parameterized type with a wildcard.
newacct
  • 119,665
  • 29
  • 163
  • 224
  • `Pair` is not a `Pair super Number>`, but `Pair` is – Bohemian Aug 08 '15 at 09:33
  • Why is `Pair` considered subtype of `Pair super Number>`. Both are of the same type, so `List super Pair<>>` or `List extends Pair<>>` should both work right? – Codebender Aug 08 '15 at 09:36
  • Alright, I think what was throwing me off was thinking about in pieces. When dealing with this level of nested cards, you have to actually think of the entire wildcard expression. For example, `? extends Pair super Number>` means "Give me a member of the **set** for which `Pair super Number>` can contain. In a similar manner, `? super Pair super Number>` means "Give me a member of a **set** for which contains `Pair super Number>`. In other words, you can't think of these as simply as the parts but rather the entire picture. – Darketh Aug 08 '15 at 17:33