[ACCEPTED]-Method overloading and choosing the most specific type-overloading

Accepted answer
Score: 26

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.

Score: 3

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.

Score: 2
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.

Score: 1

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.

Score: 1

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.

Score: 0

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

Score: 0

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.

Score: 0

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  
Score: 0

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