1

Below is the code

package org.nagark;


class baseClass{

    public void callMtd(int i){
        System.out.println("integer method"+i);
    }

    public void callMtd(double d){
        System.out.println("double method"+d);
    }
}

public class OverRidingExample {

    /**
     * @param args
     */
    public static void main(String[] args) {
        baseClass bc = new baseClass();
        bc.callMtd(10/3);
    }

}

In OverRidingExample class I am calling baseClass.callMtd method with argument 10/3(as you can see in the code). As callMtd is overloaded in baseClass, which version should be called by default? as it is overloaded method binding should happen at compile time but can computation of 10/3 happen at compile time?

reto
  • 9,995
  • 5
  • 53
  • 52
  • possible duplicate of [Java overloading rules](http://stackoverflow.com/questions/10901259/java-overloading-rules) – Smutje Aug 08 '14 at 09:35

2 Answers2

4

10/3 is the same as 3, so the int version will be called.

int would be casted to double only when no int-parametrized method present

Computation of 10/3 would happen at compilation time, as it fulfills the definition of constant expression (thanks, holger).

The method and it's full signature (including parameters types) are always resolved at compile time. For example, if you're using some jar and calling some method methodName(String x) from any class in this jar and this method changes signature (broadens) while replacing this jar with the more modern version to methodName(Object x) (no problem, isn't it?), the execution would fail.

By the way, if you're not sure, you always can look into bytecode of the generated OverRidingExample.class:

$ javap -c  OverRidingExample.class 
Compiled from "OverRidingExample.java"
public class org.nagark.OverRidingExample {
  public org.nagark.OverRidingExample();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class org/nagark/baseClass
       3: dup
       4: invokespecial #3                  // Method org/nagark/baseClass."<init>":()V
       7: astore_1
       8: aload_1
       9: iconst_3
      10: invokevirtual #4                  // Method org/nagark/baseClass.callMtd:(I)V
      13: return
}

You can see, that here's:

  1. No division, just the loading of constant (which, I suppose, is equal to 3)
  2. The int-parametrized method is called. QED

If you're not familiar with byte-code, you might read wiki article.

Community
  • 1
  • 1
Dmitry Ginzburg
  • 7,391
  • 2
  • 37
  • 48
  • That's exactly what I wrote. But there may exist some Java implementation, that wouldn't do that. – Dmitry Ginzburg Aug 08 '14 at 09:43
  • There is a [precise definition of compile time constants](http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28). You can exhibit the compiler’s behavior by checking whether the statement `byte x = 300/3;` will be correctly accepted while `byte y = 300/2;` has to be rejected. Another point is that even `""+100/3 == ""+100/3` must be `true` to fulfill the specification (and will be again a compile-time constant which implies that `""+100/3 == ""+100/3? 1: 0` is a valid `case` label in a `switch` statement…) – Holger Aug 08 '14 at 10:18
  • @Holger Okay, then my answer is wrong in some way. Will be fixed. Thanks. – Dmitry Ginzburg Aug 08 '14 at 10:20
  • @Dmitry Ginzburg: in principle, a compiler could emit instructions doing a calculation in this very specific scenario without making a difference. But there are tons of other scenarios where it makes a difference. – Holger Aug 08 '14 at 10:23
0

Compiler is looking on the type of argument when decide which overloading method to call. Your type is int. So, the method signature

public void callMtd(int i)

will be used, determined at compile time.

Roman C
  • 49,761
  • 33
  • 66
  • 176