[ACCEPTED]-Method overloading and choosing the most specific type-overloading
Java uses early binding. The most specific 31 method is chosen at compile time. The most 30 specific method is chosen by number of parameters 29 and type of parameters. Number of parameters 28 is not relevant in this case. This leaves 27 us with the type of parameters.
What type 26 do the parameters have? Both parameters 25 are expressions, using the ternary conditional 24 operator. The question reduces to: What 23 type does the conditional ternary operator 22 return? The type is computed at compile 21 time.
Given are the two expressions:
(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B
The rules 20 of type evaluation are listed here. In B
it is 19 easy, both terms are exactly the same: null
will 18 be returned (whatever type that may be) (JLS: "If the second 17 and third operands have the same type (which 16 may be the null type), then that is the 15 type of the conditional expression."). In 14 A
the second term is from a specific class. As 13 this is more specific and null
can be substituted 12 for an object of class Object
the type of the 11 whole expression is Object
(JLS: "If one 10 of the second and third operands is of the 9 null type and the type of the other is a 8 reference type, then the type of the conditional 7 expression is that reference type.").
After 6 the type evaluation of the expressions the 5 method selection is as expected.
The example 4 with if
you give is different: You call the 3 methods with objects of two different types. The 2 ternary conditional operator always is evaluated 1 to one type at compile time that fits both terms.
JLS 15.25:
The type of a conditional expression 2 is determined as follows:
[...]
- If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.
[...]
So the 1 type of
10 % 2 == 0 ? null : new Object();
is Object.
test((10%2==0)?null:new Object());
Is the same as:
Object o;
if(10%2==0)
o=null;
else
o=new Object();
test(o);
Since type of o
is Object
(just 2 like the type of (10%2==0)?null:new Object()
) test(Object)
will be always called. The 1 value of o
doesn't matter.
Your answer is : Runtime because in runtime specify 2 parameter is instance of String or not so 1 in compile-time can't find this.
This is the really nice question.
Let me 29 try to clarify your code that you have written 28 above.
- In your first method call
test(null);
In this the null
will be converted 27 into string type so calling the test(String obj)
, as per 26 JLS you are convinced with the call.
- In the second method call
test((10%2==0)?null:new 25 Object());
Which is going to return the boolean 24 "true" value. So first boolean "true" value 23 is going to auto cast into Boolean Wrapper 22 class object. Boolean wrapper Object is 21 finding the best match with your new Object()
option 20 in the ternary operator. And the method 19 calls with Object as a parameter so it calls 18 the following method
public static void test(Object 17 obj)
For the experiment sake you can try 16 the following combinations then you will 15 get better clarity.
test((10 % 2 == 0) ? new 14 Object() : "stringObj" );
test((10 % 2 == 0) ? new 13 Object() : null );
test((10 % 2 == 0) ? "stringObj" : null 12 );
- Finally in the last when you are calling with the following code.
test((10%2==0)?null:null);
This time again 11 it returns as boolean "true" value, and 10 it will again follow the same casts as explained 9 above. But this time there is no new Object()
parameter 8 is there in your ternary operator. So it 7 will be auto type cast into null
Object. Again 6 it follows same method call as the your 5 first method call.
- In the last when you asked for code if you put in
if .. else
statement. Then also the compiler doing the fair decision with the code.
if(10%2==0) { test(null); }
Here 4 all the time your if condition is true and 3 calling this code test(null)
. Therefore all the time 2 it call the firsttest(String obj)
method with String as 1 parameter as explained above.
I think your problem is that you are making 3 the wrong assumption, your expressions:
test((10%2==0)?null:new Object());
and
test((10%2==0)?null:null;
Will 2 always call test(null), and that's why they 1 will go through test (Object).
as @Banthar mentionend the ?:
operator assigns 5 a value to a variable first then evaluates 4 the condition.
On the other hand, the if
condition 3 you mentioned always returns true, so the 2 compiler will replace the whole if-else
block with 1 only the body of the if
.
1) the test()
method is determined by the type 4 of the parameter at the compilation time 3 :
test((Object) null);
test((Object)"String");
output :
Object called
Object called
2) The compiler is even smarter, the 2 compiled code is equivalent to just :
test(null);
you 1 can check the bytecode with javap -c
:
0: aconst_null
1: invokestatic #6 // Method test:(Ljava/lang/String;)V
4: return
This is what Java Language Specifications say about the problem.
If more 27 than one method declaration is both accessible 26 and applicable to a method invocation, it 25 is necessary to choose one to provide the descriptor 24 for the run-time method dispatch. The Java 23 programming language uses the rule that 22 the most specific method is chosen.
This 21 is test(String) method in your case.
And 20 because of that if you add...
public static void test(Integer obj){
System.out.println("Ingeter called");
}
it will show 19 compilation error -The method test(String) is 18 ambiguous for the type OverloadingTest.
Just 17 like JLS says:
It is possible that no method 16 is the most specific, because there are two 15 or more maximally specific methods. In this 14 case:
If all the maximally specific methods 13 have the same signature, then: If one 12 of the maximally specific methods is not 11 declared abstract, it is the most specific 10 method. Otherwise, all the maximally specific methods 9 are necessarily declared abstract. The most 8 specific method is chosen arbitrarily 7 among the maximally specific methods. However, the most 6 specific method is considered to throw a 5 checked exception if and only if that 4 exception is declared in the throws clauses 3 of each of the maximally specific methods. Otherwise, we 2 say that the method invocation is ambiguous, and 1 a compile-time error occurs.
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.