I was playing with ternary operator and noticed something odd. I have code below:
class Main {
static void foo(int a){
System.out.println("int");
}
static void foo(String a){
System.out.println("String");
}
static void foo(Object a){
System.out.println("object");
}
public static void main(String[] args) {
foo(2==3 ? 0xF00:"bar");
System.out.println((2==3 ? 0xF00:"bar").getClass().getName());
}
}
Which results in
object
java.lang.String
First line of result shows that this instruction passed to foo method with object parameter.
Second line that the instruction itself results in String.
Question:
Why if result is String compiler decides to go with Object?
Is this because of the type ambiguity?
If yes then why getting class name returned java.lang.String?
Yes, we can, but with one proviso… There is no block demarcation so that action should be simple, else it would be better to abstract it away in a function and call the function from the ternary.
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.
Conditional or Ternary Operator (?:) in C/C++ The conditional operator is kind of similar to the if-else statement as it does follow the same algorithm as of if-else statement but the conditional operator takes less space and helps to write the if-else statements in the shortest way possible.
The ternary operator take three arguments: The first is a comparison argument. The second is the result upon a true comparison. The third is the result upon a false comparison.
A ternary operator with conditional expression performs real-life scenario like for different conditions different actions are performed. Ternary Operator in SQL also be termed as Conditional Operator can be defined as a unique decision-making operator found in many programming languages.
If we compare syntax of ternary operator with above example, then − First, expression a > b is evaluated, which evaluates to Boolean false as value of variable 'a' is smaller than value of variable 'b'. Hence value of variable 'b' i.e. '20' is returned which becomes final result and gets assigned to variable 'max'.
In Java, the ternary operator is a type of Java conditional operator. In this section, we will discuss the ternary operator in Java with proper examples. The meaning of ternary is composed of three parts.
In C programming, we can also assign the expression of the ternary operator to a variable. For example, Here, if the test condition is true, expression1 will be assigned to the variable. Otherwise, expression2 will be assigned. In the above example, the test condition (operator == '+') will always be true.
You can skip to Summary if not interested in reading.
Refer the JavaDoc here: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Under 15.25.3. Reference Conditional Expressions It says:
The type of the conditional expression is the result of applying capture conversion
For capture conversion : https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.10
Summary:
For type determination, capture conversion is used, wherein for your example int is first boxed to Integer and then the closest common super class of Integer and String is fetched, which is Object class. So the type for the Conditional Expression is Object and so the method with Object as parameter is called.
Now for second part, the Conditional operator is evaluated first, then it is unboxed and then .getClass() is evaluated. So it prints java.lang.String.
This is also documented here: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Under 15.25. Conditional Operator ? :
At run time, the first operand expression of the conditional expression is evaluated first. If necessary, unboxing conversion is performed on the result.
In Java, you have compile time type information and you have run time type information. Compile time type information is what the compiler can deduce about the type of a value or expression just by looking at it, but without executing it. When the compiler sees the expression
2 == 3 ? 0xF00 : "bar"
It does not know whether 2 == 3
will be true or false, because it does not execute code. So all it knows is that the result can be an Integer
, or a String
. So when the time comes to pick which foo
method to call, it picks the one that accepts Object
, since that is the only one that it knows will work in both scenarios.
However, when the code is actually running, 2 == 3
will be false, and the result will be a String
, whose getClass()
method will return String.class
. And that is what you need to note: getClass()
does not return the type that the variable had at compile time, but it returns the actual type of the object that the variable holds at run time. i.e.
Object o = "Hello!";
System.out.println(o.getClass());
will print java.lang.String
, because even though to the compiler it is an Object
, at run time it is actually a String
.
At compile stage, the compiler noticed that the result of 2 == 3 ? 0xF00 : "bar"
could be int or String. To be compatible with both, it decide to call foo(Object a)
.
At runtime, the result of 2 == 3 ? 0xF00 : "bar"
is String bar
.
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