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?
As for the rationale:
new Foo<?>should probably better be written asnew Foo<Object>, so the compiler restriction here forces to write the code as readable as you can. The last example could likewise benew Foo<Mak>(), as there is nothing you can do on aFoo<? extends Mal>that you cannot do on aFoo<Mal>. Note that the converse isn’t true: aFoo<Mal>might acceptMalarguments where aFoo<? extends Mal>doesn’t.On the other hand, you really might want a
Fooobject which can handleBarobjects of any kind, soFoo<Bar<?>>makes perfect sense. This would be the case if you only access methods ofBarwhich don’t rely on the type argument. There is nothing for the compiler to complain here.