Reputation: 137
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?
Upvotes: 5
Views: 5866
Reputation: 2626
When you are calling the function
test(5>8? 5:8);
Method (in present case) is meant to send the parameter hence whole thing inside the parentheses is considered as parameter and there is no appropriate/suitable method to handle such kind of call (whose parameter should be Object) as you are evaluating int and String in one of the statements . Hence the Ternary operator cannot be implemented there.
Hence you can use code like this
(5 > 8) ? test(param1): test(param2);
or create another test method which accepts Object as parameter and then evaluate things inside that test method. like this
void test(Object o){
//manipulate things here
}
Upvotes: 0
Reputation: 79828
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
, both 5
and 8
are int
, so this whole expression has type int
.5 > 8 ? "he" : "ha"
, both "he"
and "ha"
are String
, so this whole expression has type String
.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.
Upvotes: 8
Reputation: 5166
You are calling the method before the expression is evaluated. Since the method doesn't have an overload for test(Object o), it doesn't work.
Call the method after resolving the left side expression.
5>8?test(5):test("ha")
Upvotes: 0