The conditional operator ? : uses the boolean value of one expression to decide which of the two other expressions should be evaluated.
The conditional operator is syntactically right-associative. For instance a?b:c?d:e?f:g is equivalent to a?b:(c?d:(e?f:g)).
Format:
ConditionalExpression:
ConditionalOrExpression
ConditionalOrExpression ? Expression : ConditionalExpression
EXP00-A. Use same type for second and third operands in conditional expressions
- If the value of the first operand is true, then the second operand expression is chosen
- If the value of the first operand is false, then the third operand expression is chosen
The rules that define the resultant type are given below, where * refers to constant expressions of type int
(such as '0' or variables declared as final):
Operand 2 |
Operand 3 |
Resultant type |
---|---|---|
type T |
type T |
type T |
boolean |
Boolean |
boolean |
Boolean |
boolean |
boolean |
null |
reference |
reference |
reference |
null |
reference |
byte or Byte |
short or Short |
short |
short or Short |
byte or Byte |
short |
byte,short,char |
const int* |
byte,short,char if value of int representable |
const int* |
byte,short,char |
byte,short,char if value of int representable |
Byte |
const int* |
byte if int is representable as byte |
const int* |
Byte |
byte if int is representable as byte |
Short |
const int* |
short if int is representable as short |
const int* |
Short |
short if int is representable as short |
Character |
const int* |
char if int is representable as char |
const int* |
Character |
char if int is representable as char |
other |
other |
promoted type of the 2nd and 3rd operands |
T1 = boxing conversion (S1) |
T2 = boxing conversion(S2) |
apply capture conversion to lub(T1,T2) |
Non-Compliant Code Example
This non-compliant example prints A65
instead of AA
. The first print statement prints the value of alpha
as type char
, that is as A
since the third operand is a constant expression of type int
(0). The second statement, however, prints 65
, the integer equivalent of A
. This is because of numeric promotion between the second operand (int
) and the third (char
) resulting from the use of variable i
.
public class expr { public static void main(String[] args) { char alpha = 'A'; int i = 0; System.out.print(true ? alpha : 0); System.out.print(false ? i : alpha); } }
Compliant Solution
This compliant solution recommends the use of same types for second and third operands. This helps avoid confusion due to clearer semantics.
public class expr { public static void main(String[] args) { char alpha = 'A'; char i = 0; //declare as char System.out.print(true ? alpha : 0); System.out.print(false ? i : alpha); } }
Another solution is to declare the offending type as final. As a result, it turns into a constant expression and numeric promotion does not occur.
public class expr { public static void main(String[] args) { char alpha = 'A'; int i = 0; System.out.print(true ? alpha : 0); System.out.print(false ? i : alpha); } }
References
JLS 15.25 Conditional Operator ? :
Java Puzzlers, Traps, Pitfalls, Corner Cases 2.8