简体   繁体   中英

Java Overloading - will computation happens at compile time or runtime?

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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM