Nick
Nick

Reputation: 2514

Java Generics - Expected return type different than actual

Here is an example of some code I'm working on:

public interface FooMaker<T extends Enum<T> & FooType>
{
      public List<Foo<T>> getFoos(String bar);
}

Let's further assume there will be many different concrete implementations of FooMaker. So I wrote some code to utilize the FooMakers.

FooMaker<?> maker = Foos.getRandomMaker();
List<Foo<?>> fooList = maker.getFoos("bar");  //error here!

The second line of code causes the issue, eclipse tells me the code should be:

FooMaker<?> maker = Foos.getRandomMaker();
List<?> fooList = maker.getFoos("bar");

I'm having trouble understanding why the Foo declaration as the parameterized type in List has to go away to make the return type correct.

Any ideas?

Upvotes: 5

Views: 344

Answers (3)

Luke Hutteman
Luke Hutteman

Reputation: 1931

Try this instead:

List<? extends Foo<? extends Enum<?>>> fooList = maker.getFoos("bar");

The problem is that if this has been allowed:

List<Foo<?>> fooList = maker.getFoos("bar");

Then by extension, you would've been able to get away with this as well:

Foo<?> foo1 = new Foo<String>();
Foo<?> foo2 = new Foo<Integer>();
fooList.add(foo1);
fooList.add(foo2);

Which would invalidate the generic contract of the returned list.

To prevent this, the java compiler forces the return type to be wildcard-based, meaning Foo can be used as a return-type (to pull elements out of the list) but you will not be able to add wildcard-based Foo types to your list.

Upvotes: 1

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

Usual:

class Bar {}
class Baz {}

FooMaker<?> maker = new FooMaker<Bar>();
List<Foo<?>> fooList = maker.getFoos("bar");  //error here!
fooList.add(new Foo<Baz>());                  //cock-up here!

Upvotes: 1

matt b
matt b

Reputation: 140051

Because you are declaring maker as FooMaker<?>. Why wouldn't you declare it as the type of AwesomeFooMaker if you know what specific T AwesomeFooMaker returns?

Upvotes: 0

Related Questions