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?
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.5 > 8 ? 5 : 8, both5and8areint, so this whole expression has typeint.5 > 8 ? "he" : "ha", both"he"and"ha"areString, so this whole expression has typeString.5 > 8 ? 5 : "ha", the most specific type that fits both5and"ha"isObject. So this whole expression has typeObject.Now since you have versions of
testthat acceptintand acceptString, the expressionstest ( 5 > 8 ? 5 : 8 )andtest ( 5 > 8 ? "he" : "ha" )both compile.But if you don't have a version of
testthat acceptsObject, thentest ( 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
nulloperands, auto-boxing and auto-unboxing.