Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GenericWildcard is not applicable [duplicate]

Tags:

java

generics

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?

like image 221
Micha Wiedenmann Avatar asked Jul 02 '13 08:07

Micha Wiedenmann


1 Answers

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.

like image 84
Matyas Avatar answered Sep 30 '22 20:09

Matyas