Proposal: Improved Wildcard Syntax for Java

Howard Lovatt howard.lovatt at
Sat Mar 14 18:41:37 PDT 2009

Neal Gafter has proposed replacing the current wildcard syntax with in
and out instead of extends and super; an alternative to the current
extends/super and Neal's proposal would be to deprecate the current
wildcards and to change to the behaviour to that of arrays (covariant
only). In particular to change the wildcard syntax to
SomeClass<SomeOtherClass> for variables, arguments, or fields, class
AClass<AnotherClass T> for classes, and <SomeClass T> for methods
where T is compulsory when declaring classes or methods but not used
when declaring variables etc. (i.e. exactly like method arguments).
This new syntax is similar in behaviour to the current syntax
SomeClass<T extends SomeOtherClass> (the difference is that the new
does not issue a warning for covariant assignment).

This proposal deprecates the concepts of SomeClass<T super
SomeOtherClass>, SomeClass<?>, and SomeClass<SomeOtherClass> in the
current syntax. Generics are made covariant so that List<Object> lo =
new ArrayList<String>() is OK and does not issue a warning (like
arrays). If "lo" form the previous example has an object added to it,
lo.add( new Object() ), then if this produces an error or not is
dependant on the class in question (in the case or ArrayList it
wouldn't). See
for more detail.

At the same time I propose cleaning up other pain points with
generics, in particular:

1. Deprecate raw declarations, new ArrayList() becomes a deprecated
warning - you need to say new ArrayList<Object>().

2a. Deprecate self references, you get a deprecated warning for class
Type<T extends Type<T>>, you wouldn't use generics in this case.

2b. It follows that <Type<T> T> is an error in the new syntax, see
next point for how you would do this.

3. Deprecate the ability to specify multiple bounds, e.g. instead of
static <T extends Object & Comparable<? super T>> T max(Collection<?
extends T>) you write static <Comparable T> T max(Collection<T>) (note
Comparable would not be parameterised with the new syntax since you
would almost always want Comparable<Object>).

4. Allow arrays of parameterised types, List<String>[] lsa = new
ArrayList<String>[10] is OK (you may get a runtime exception though if
you misuse the feature).

Examples of use of proposed new syntax are:

boolean isAnnotationPresent( Class<Annotation> annotationClass ); //
was: boolean isAnnotationPresent( Class<? extends Annotation>
annotationClass );

static createList( Collection<Number> coll ); // was: static
createList( Collection<? extends Number> coll );

static <Comparable T> void sort( List<T> list ); // was: static <T
extends Comparable<? super T>> void sort( List<T> list );

static Enum valueOf( Class<Enum> enum, String name ); // was: static
<T extends Enum<T>> T valueOf( Class<Enum> enum, String name );

The disadvantage of this proposal is that you can now get the
equivalent of ArrayStoreExceptions, the reason that this is acceptable
is that ArrayStoreExceptions are rare (I have never had one). For
compatibility the existing syntax would still be allowed, but would
issue a deprecated warning. The reason that I am proposing deprecating
wildcards is that they are not worth the trouble (they have a poor
cost/benifit ratio - less is more). I know the language pedants will
hate this proposal, but I think the vast majority of Java users would
welcome this change.

This proposal has some overlap with the proposal to infer generic
types in that they both concern generic declarations, but are
otherwise orthogonal. The collections library, in particular methods
like sort (see above) and interfaces like Comparable, and enum class
would need updating to the new syntax and this new library would have
to be supplied as a module so that old code could use the old library
(nt 100% compatible).

So I am proposing eventually removing something from the language
(actually replacing) - is removing a feature a first on coin-dev?

More information about the coin-dev mailing list