9

I have a function

public static void bar (final List<List<?>> list)
{
}

which I can call with a wildcard (<?>)

bar(new ArrayList<List<?>>());

but not with another type (e.g. String)

// The method bar(List<List<?>>) in the type Foo is not
// applicable for the arguments (ArrayList<List<String>>)
bar(new ArrayList<List<String>>());

However this works for the similar function

public static void foo(List<?> l)
{
}

public static void main(String[] args)
{
    // no error
    foo(new ArrayList<String>());
}

Can you please explain, why the compiler complains in the first case but not in the second?

Micha Wiedenmann
  • 19,979
  • 21
  • 92
  • 137

1 Answers1

4

You should declare your method as:

private void bar(final List<? extends List<?>> lists) {...}

In this case the call bar(new ArrayList<List<String>>()); would work.

The explanation

In short:

List<SomeType> - The compiler will expect a call with exactly the same type. List<? extends SomeType> - The compiler will expect a call with a class that is a compatible (sublass) with SomeType.

In your case a definition

void bar (final List<List<?>> list)

will expect a parameter whose definition is exactly List<List<?>>() nestedList;

On the other hand, when you specify your method as:

void bar(final List<? extends List<?>> lists)

Then you're saying that you have a list whose types are upper-bounded by List<?>, so ArrayList<String> would be a valid candidate for the nested list

From Oracle docs:

There is a small but very important difference here: we have replaced the type List with List. Now drawAll() will accept lists of any subclass of Shape, so we can now call it on a List if we want.

List is an example of a bounded wildcard. The ? stands for an unknown type, just like the wildcards we saw earlier. However, in this case, we know that this unknown type is in fact a subtype of Shape. (Note: It could be Shape itself, or some subclass; it need not literally extend Shape.) We say that Shape is the upper bound of the wildcard.

Matyas
  • 13,473
  • 3
  • 60
  • 73