My Practice Tests book contains this question on the ternary operator:
// What is the output of the following application?
public class Transportation {
public static String travel(int distance) {
return(distance < 1000 ? "train" : 10);
}
public static void main(String[] args) {
travel(500);
}
}
It does not compile. The explanation given is the following:
Ternary operations require both right-hand expressions to be of compatible data types. In this example, the first right-hand expression of the outer ternary operation is of type String, while the second right-hand expression is of type int. Since these data types are incompatible, the code does not compile, and Option C is the correct answer.
Is that really the reason? It looks to me like this example doesn't compile because 10 is not a String and a String is what the method must return.
I'm asking because
System.out.println(distance < 1000 ? "train" : 10);
compiles and runs without a problem.
The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.
?: = Question Mark Colon is also called C Ternary Operator.
Except in very simple cases, you should discourage the use of nested ternary operators. It makes the code harder to read because, indirectly, your eyes scan the code vertically. When you use a nested ternary operator, you have to look more carefully than when you have a conventional operator.
The ternary operator is an operator that takes three arguments. The first argument is a comparison argument, the second is the result upon a true comparison, and the third is the result upon a false comparison. If it helps you can think of the operator as shortened way of writing an if-else statement.
Your method declares that the return type is String
. Any return
statement must produce an expression that is compatible with the declared return type.
In this case, however, the return type can be int
, which explains why the compiler rejects it.
This is not specific to the ternary operator, it can be reproduced with an equivalent if
/else
block as well:
if(distance < 1000)
return "train"; //This part is valid
else
return 10; //This line will be rejected by the compiler
For the same reason, the last line will fail to compile. This is simply because of basic type checking.
System.out.println(distance < 1000 ? "train" : 10); compiles and runs without a problem.
This is because the compiler detects a common type for both String
and int
, which is Object
, and resolves to choose this signature:
java.io.PrintStream#println(Object x) // available in the target class
This, however, isn't applicable to the method return type.
If you changed your return type to Object
, your code would compile too. But that's of course not what you're trying to do.
Ternary operations require both right-hand expressions to be of compatible data types
-> This part is in fact valid. here's a way to interpret it: each of the two expressions must be individually compatible:
String value = distance > 1000 ?
"train" //this must be compatible with String
:
10 //this too must be compatible with String (it isn't)
In contrast:
Object value = distance > 1000 ?
"train" //this must be compatible with Object (it is)
:
10 //this too must be compatible with Object (it is)
In other words, the call to System.out.println(distance < 1000 ? "train" : 10)
is similar to the last example above, where the expected type is compatible with both expressions.
is that really the reason? It looks to me like this example doesn't compile because 10 is not a String and a String is what the method must return
Both your reasoning and the answer of the author are right.
I think that the right answer to your question is the union of them.
1) the Ternary operator is invalid
because
2) in the current context, the type that you assigned it to : an int
cannot be assigned to a String
.
You can check it with the error messages emitted by the compiler.
Here, you have to consider that :
return(distance < 1000 ? "train" : 10);
as two things to evaluate by the compiler :
1) distance < 1000 ? "train" : 10
// produces a result
2) returns (the produced result);
// return the result that should be assignable to a String according to the method return type
Actually, the compilation error :
Transportation.java:3: error: incompatible types: bad type in conditional expression return(distance < 1000 ? "train" : 10);
int cannot be converted to String
refers the both errors : the error in the conditional expression and its cause : the error of the incompatibility between int and String.
So the compilation error that refers only the incompatibility between int and String in the return
will occur only if the ternary is valid at compile time.
Write a valid ternary expression and you could see that the compiler will signal only the error about the return
statement :
public static String travel(int distance) {
return(distance < 1000 ? 15 : 10);
}
error: incompatible types: int cannot be converted to String
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