Proposal: Improved Wildcard Syntax for Java (original) (raw)

Neal Gafter neal at gafter.com
Sat Mar 14 20:58:37 PDT 2009


My main concern is that this sounds like a significant change to the type system, and therefore almost certainly out of scope for project Coin.

I have no idea how you would specify or implement the proposed compile-time diagnostics (such as an error on lo.add(new Object())) or runtime type tests (such as the "equivalent of ArrayStoreExceptions"). The link with "more details" actually has fewer details than this email. I don't see how you plan to make the change backward compatible. Without something resembling a specification, it's hard to evaluate further.

On Sat, Mar 14, 2009 at 6:41 PM, Howard Lovatt <howard.lovatt at iee.org> wrote:

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 for variables, arguments, or fields, class AClass for classes, and 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 (the difference is that the new does not issue a warning for covariant assignment).

This proposal deprecates the concepts of SomeClass, SomeClass<?>, and SomeClass in the current syntax. Generics are made covariant so that List lo = new ArrayList() 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 http://www.artima.com/weblogs/viewpost.jsp?thread=222021 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(). 2a. Deprecate self references, you get a deprecated warning for class Type<T extends Type>, you wouldn't use generics in this case. 2b. It follows that <Type 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 T max(Collection) (note Comparable would not be parameterised with the new syntax since you would almost always want Comparable). 4. Allow arrays of parameterised types, List[] lsa = new ArrayList[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 annotationClass ); // was: boolean isAnnotationPresent( Class<? extends Annotation> annotationClass ); static createList( Collection coll ); // was: static createList( Collection<? extends Number> coll ); static void sort( List list ); // was: static <T_ _extends Comparable<? super T>> void sort( List list ); static Enum valueOf( Class enum, String name ); // was: static <T extends Enum> T valueOf( Class 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