Java重载 - 将在编译时或运行时进行计算吗?

时间:2014-08-08 09:32:47

标签: java overloading

以下是代码

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);
    }

}

OverRidingExample类中,我使用参数10/3调用baseClass.callMtd方法(正如您在代码中看到的那样)。由于callMtd在baseClass中重载,默认情况下应该调用哪个版本?因为它是重载的方法绑定应该在编译时发生,但可以在编译时计算10/3吗?

2 个答案:

答案 0 :(得分:4)

10/33相同,因此将调用int版本。

仅当没有int - 参数化方法存在时,

double将被投放到int

10/3的计算将在编译时发生,因为它满足常量表达式的definition(谢谢,holger)。

该方法及其完整签名(包括参数类型)始终在编译时解析。例如,如果你正在使用一些jar并从这个jar中的任何类调用一些方法methodName(String x),这个方法会更改签名(扩展),同时用更现代的版本替换这个jar到methodName(Object x)(不问题,不是吗?),执行会失败。

顺便说一下,如果你不确定,你总是可以查看生成的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
}

你可以看到,这是:

  1. 没有除法,只是加载常数(我认为,等于3)
  2. 调用int - 参数化方法。 QED
  3. 如果您不熟悉字节码,可以阅读wiki文章。

答案 1 :(得分:0)

编译器在决定调用哪个重载方法时查看参数类型。您的类型为int。那么,方法签名

public void callMtd(int i)
将使用

,在编译时确定。