Table 15.25-B in JLS version 8 says that the type of a conditional expression
true ? null : 0.0
is lub(null,Double)
, where lub
appears to be some crazy incomprehensible thing from section 4.10.4.
This appears to be distinct from the Double
type somehow, or they probably would have just written Double
, like they did elsewhere in the table. It's not clear what the difference could be, though. I tried to work it out from section 4.10.4, but by the time I got to the part about
Let lub(U1 ... Uk) be:
Best(W1) & ... & Best(Wr)
it seemed like they were saying that this type is an intersection type of the null and Double types, which makes no sense.
What is lub(null, Double)
? How does a conditional expression with this type behave differently from if its type were just defined as Double
?
It's just Double
.
Informally, lub(null, Double)
is (a decent approximation to) the most specific type that contains all values of the null
type and the Double
type, and the most specific such type is Double
.
Formally, we can work through the definition of lub
in JLS section 4.10.4, and we find that lub(null, Double)
is Double
:
The least upper bound, or "lub", of a set of reference types is a shared supertype that is more specific than any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound). This type, lub(U1, ..., Uk), is determined as follows.
If k = 1, then the lub is the type itself: lub(U) = U.
Otherwise:
For each Ui (1 ≤ i ≤ k):
Let ST(Ui) be the set of supertypes of Ui.
ST(null) is the set of all reference types, and ST(Double) is {Object, Number, Double}.
Let EST(Ui), the set of erased supertypes of Ui, be:
EST(Ui) = { |W| | W in ST(Ui) } where |W| is the erasure of W.
EST(null) is the set of the erasures of all reference types, and EST(Double) is {Object, Number, Double}.
Let EC, the erased candidate set for U1 ... Uk, be the intersection of all the sets EST(Ui) (1 ≤ i ≤ k).
EC is the intersection of EST(null) and EST(Double), so EC is {Object, Number, Double}.
Let MEC, the minimal erased candidate set for U1 ... Uk, be:
MEC = { V | V in EC, and for all W ≠ V in EC, it is not the case that W <: V }
MEC is the set of all types in EC that have no proper subtype in EC. Double is a proper subtype of both Number and Object, so MEC = {Double}. (W <: V
means that the type W
is a subtype of the type V
. A type is considered a subtype of itself, so they specify W ≠ V to count only proper subtypes.)
For any element G of MEC that is a generic type:
[lots of text]
MEC contains no generic types, so we can skip this.
Let lub(U1 ... Uk) be:
Best(W1) & ... & Best(Wr)
where Wi (1 ≤ i ≤ r) are the elements of MEC, the minimal erased candidate set of U1 ... Uk;
and where, if any of these elements are generic, we use the candidate parameterization (so as to recover type arguments):
Best(X) = Candidate(X) if X is generic; X otherwise.
Candidate
was defined in the part we skipped; we can still skip it, since it only matters for generic types.
lub(null, Double) is Best(Double), and Best(Double) is Double, so lub(null, Double) is Double.
I believe that lub(null, Double) === Double
. Not sure why use lub(null, Double)
. Maybe to allow for change in the semantics of the null type in the future?
Here's my reasoning. By definition, LUB = lub(T_1, ..., T_n)
, the Least Upper Bound of types T_1,...,T_n, is a type that is a supertype of all T_1, ..., T_n such that there's no proper subtype of LUB
that is also a supertype of all T_1,...,T_n (ie, it's the most specific type that's simultaneously a supertype of T_1,...,T_n
).
By definition, the type of the null
expression is the null type. Also by definition, all reference types except the null type are direct supertypes of the null type.
Double
is a supertype of the null type. Double
is also a supertype of itself, the Double
type. So Double
does satisfies the condition is a supertype of all T_1,...,T_n
. On the other hand, there's no other type that can be a proper subtype of Double
and still be a supertype of Double
. Hence, Double
is the lub(null, Double)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With