I am also not sure why there is a limitation. You can try sending a friendly email to the Java 5 Generics developers (mainly Gilad Bracha and Neal Gafter).
My assumption is that they only wanted to maintain an absolute minimum of intersection types (which is essentially a few limitations) to make the language no more complicated than necessary. An intersection cannot be used as a type annotation; a programmer can only express an intersection when it appears as the upper bound of a type variable.
And why was this case even supported? The answer is that multiple borders allow you to control erasure, which allows you to maintain binary compatibility when creating existing classes. As explained in section 17.4 of the book by Naphthalene and Wadler, the max method would logically have the following signature:
public static <T extends Comparable<? super T>> T max(Collection<? extends T> coll)
However, this erases:
public static Comparable max(Collection coll)
Which does not match the historical signature of max and makes old customers break. For multiple boundaries, only the leftmost boundary is taken into account for erasure, therefore, if max specified with the following signature:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
Then erasing his signature becomes:
public static Object max(Collection coll)
which is equal to the signature max before Generics.
It seems plausible that the Java developers only cared about this simple case and limited other (more advanced) applications of intersection types because they are simply not sure about the complexity that it can bring. Therefore, the reason for this design decision should not be a possible security problem (as follows from this question).
More discussion of intersection types and generic restrictions in the upcoming OOPSLA paper .
Bruno De Fraine Oct 13 '08 at 12:25 2008-10-13 12:25
source share