Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary operator with different types of expressions [duplicate]

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:

  1. Why if result is String compiler decides to go with Object?

  2. Is this because of the type ambiguity?

  3. If yes then why getting class name returned java.lang.String?

like image 509
Lemonov Avatar asked Jun 13 '18 14:06

Lemonov


People also ask

Can ternary operators contain multiple actions?

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.

Can ternary operator have 3 conditions?

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.

How ternary operator is similar to if-else statements?

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.

What are the three arguments of a ternary operator?

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.

What is a ternary operator with conditional expression?

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.

How to compare syntax of ternary operator with example?

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'.

What is the ternary operator in Java?

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.

How to assign a ternary operator to a variable in C?

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.


3 Answers

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.

like image 126
Shubham Kadlag Avatar answered Oct 20 '22 16:10

Shubham Kadlag


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.

like image 41
Leo Aso Avatar answered Oct 20 '22 17:10

Leo Aso


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.

like image 41
xingbin Avatar answered Oct 20 '22 17:10

xingbin