Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics and Wildcards: Java likes "new Foo<Bar<?>>"

Tags:

java

generics

Alright, so Java doesn't allow the following:

Foo<?> hello = new Foo<?>();

This makes sense-- after all, what's the point of generics if you're just gonna box/unbox everything anyways?

What's weird, is Java does allow this:

Foo<Bar<?>> howdy = new Foo<Bar<?>>();

Granted, this actually accomplishes more, though at some point, there would be a cast to get whatever Bar is working with. But if Java is okay with some specificity, why doesn't it allow this?:

Foo<? extends Mal> bonjour = new Foo<? extends Mal>();

The only reason I ask is I'm fixing to rely on the "wildcard inside a class parameter of a constructor", and would seriously like to know the implications/intent behind it.

EDIT: To clarify my question, on what grounds are these statements allowed/disallowed? I'm aware that "Java doesn't permit wildcards in constructors", but the question is, why all this weirdness? Why aren't bounded wildcards allowed if nested wildcards are okay?

like image 588
Philip Guin Avatar asked Jul 18 '12 21:07

Philip Guin


1 Answers

As for the rationale: new Foo<?> should probably better be written as new Foo<Object>, so the compiler restriction here forces to write the code as readable as you can. The last example could likewise be new Foo<Mak>(), as there is nothing you can do on a Foo<? extends Mal> that you cannot do on a Foo<Mal>. Note that the converse isn't true: a Foo<Mal> might accept Mal arguments where a Foo<? extends Mal> doesn't.

On the other hand, you really might want a Foo object which can handle Bar objects of any kind, so Foo<Bar<?>> makes perfect sense. This would be the case if you only access methods of Bar which don't rely on the type argument. There is nothing for the compiler to complain here.

like image 78
MvG Avatar answered Sep 22 '22 12:09

MvG