I’ve been using Java 5’s generics a lot lately, and I’ve been thinking about what about the design works, and what needs improvement. Here’s a list of some things I think Java’s generics needs.
1. Cleaner syntax
My main problem with generics is that the syntax is so verbose. For example:
private Set<OutputPortValueListener<? super V>> listeners
= new CopyOnWriteArraySet<OutputPortValueListener<? super V>>();
I think there needs to be a way to tell the compiler to figure out what the type arguments for some things must be, like this:
private Set<OutputPortValueListener<? super V>> listeners
= new CopyOnWriteArraySet<...>();
The compiler could easily figure out what the “…” needed to be replaced with.
2. Stronger inference of generic type arguments
Java’s type inference is intentionally weaker than it could be. In fact, it is weaker than it was before 5.0’s release. Sun’s compiler team decided it would be too difficult to document the advanced type inference capabilities of javac in the Java Language Specification, so they simply removed them. Now, code like this won’t compile, when it would have with earlier versions of javac:
SortedSet<Map.Entry<Integer,Port<?>>> entries
= new TreeSet<Map.Entry<Integer,Port<?>>>(KeyComparator.getInstance());
...
class KeyComparator<K extends Comparable<? super K>>
implements Comparator<Map.Entry<K, ?>> {
public static <K extends Comparable<? super K>> KeyComparator<K> getInstance() {
return new KeyComparator<K>();
}
public int compare(Map.Entry<K, ?> entry, Map.Entry<K, ?> entry1) {
return entry.getKey().compareTo(entry1.getKey());
}
}
To compile, the underlined part needs to be replaced with “KeyComparator.<Integer>getInstance()”, because javac can’t figure out that it needs the <Integer> type argument. As I said, earlier versions of javac didn’t need the explicit type argument for this type of inference.
3. Inferred type bounds
As I’ve shown already, right now javac requires you to be verbose in your generics code in several ways. Another way is with generic type bounds. The following code will not compile:
(more…)