Search code examples
javareturn-valueternary-operatorocpjp

Passing method argument through ternary operator in java


Code:

public class Foo {

    static void test(String s){
        System.out.println("String called");
    }

    static void test(int s){
        System.out.println("int called");
    }

    public static void main(String[] args) throws Exception {

        test(5>8? 5:8);         // Line 1
        test(5>8? "he":"ha");   // Line 2

        test(5>8? 5:"ha");      // Line 3

        System.out.println(5<8? 5:"ha"); //Line 4
    }
}

When I execute this code I get the following Error at Line 3

Foo.java:24: error: no suitable method found for test(INT#1)
                test(5>8? 5:"ha");              // Line 3
                ^

Using similar type in the ternary operator does not give error. But using different types gives error only to the method call test(5>8? 5:"ha"); but it works for the call System.out.println(5<8? 5:"ha");

When I add another overloaded method static void test(Object s){}, then the //Line 3 compiles.

Can anyone please explain me this scenario?


Solution

  • Every expression in Java has a type. There are some complicated rules in the Java Language Specification, in the section on the conditional operator that tell us how to find the type of a conditional expression such as 5 > 8 ? 5 : "ha". But in simple terms, you always get the most specific type that both the second and third arguments are members of.

    • For 5 > 8 ? 5 : 8, both 5 and 8 are int, so this whole expression has type int.
    • For 5 > 8 ? "he" : "ha", both "he" and "ha" are String, so this whole expression has type String.
    • For 5 > 8 ? 5 : "ha", the most specific type that fits both 5 and "ha" is Object. So this whole expression has type Object.

    Now since you have versions of test that accept int and accept String, the expressions test ( 5 > 8 ? 5 : 8 ) and test ( 5 > 8 ? "he" : "ha" ) both compile.

    But if you don't have a version of test that accepts Object, then test ( 5 > 8 ? 5 : "ha" ) can't compile.

    This is an over-simplification. The rules are significantly more complicated than I've described, but this is mostly because they consider the various cases involving null operands, auto-boxing and auto-unboxing.