Can someone explain why this code?
Collection c = (5 == 5) ? new ArrayList() : new HashSet();
produces the following compiler error:
Incompatible conditional operand types ArrayList and HashSet
For reasons that I don't understand, the following fixes the problem
Collection c = (5 == 5) ? (Collection) new ArrayList() : new HashSet();
I'm using Java 1.4.
This was a bug in 1.4 and has been fixed according bugreport 5080917.
Evaluation This is a bug.
xxxxx@xxxxx 2004-07-30
Daniel more or less gets this right, but has deleted his answer (with five up votes).
Relevant quote from 2nd Ed JLS (1.2-1.4)
- If the second and third operands are
of different reference types, then it
must be possible to convert one of
the types to the other type (call
this latter type T) by assignment
conversion (§5.2); the type of the
conditional expression is T. It is a
compile-time error if neither type is
assignment compatible with the other
type.
One of the types needs to be convertible to the other, which is not true of ArrayList
and HashSet
but is true of Collection
and HashSet
and of ArrayList
and Collection
.
In 3rd Ed JLS (1.5+)
- Otherwise, the second and third
operands are of types S1 and S2
respectively. Let T1 be the type that
results from applying boxing
conversion to S1, and let T2 be the
type that results from applying
boxing conversion to S2. The type of
the conditional expression is the
result of applying capture conversion
(§5.1.10) to lub(T1, T2)
(§15.12.2.7).
This does the obvious thing, which as it turns out is more difficult to specify and implement (I unintentionally got an early version of javac to crash on it when one of the expressions was void
). IIRC, this was work done as part of generics.