简体   繁体   English

Java重载-计算是否会在编译时或运行时进行?

[英]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). OverRidingExample类中,我正在调用带有参数10/3的baseClass.callMtd方法(如您在代码中所见)。 As callMtd is overloaded in baseClass, which version should be called by default? 由于callMtd在baseClass中已重载,因此默认情况下应调用哪个版本? as it is overloaded method binding should happen at compile time but can computation of 10/3 happen at compile time? 因为它是重载方法绑定应该在编译时发生,但是10/3的计算是否可以在编译时发生?

10/3 is the same as 3 , so the int version will be called. 10/33相同,因此将调用int版本。

int would be casted to double only when no int -parametrized method present 仅当不存在int参数化方法时, int才会强制转换为double

Computation of 10/3 would happen at compilation time, as it fulfills the definition of constant expression (thanks, holger ). 10/3计算将在编译时进行,因为它满足了常量表达式的定义 (感谢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. 例如,如果您使用某个jar并从此jar中的任何类调用某个方法methodName(String x) ,并且此方法更改了签名(广泛使用),同时将该jar用更现代的版本替换为methodName(Object x) (否问题,不是吗?),执行将失败。

By the way, if you're not sure, you always can look into bytecode of the generated OverRidingExample.class : 顺便说一句,如果不确定,您总是可以查看生成的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) 没有除法,只有常数的加载(我想等于3)
  2. The int -parametrized method is called. 调用int参数化方法。 QED 优质教育

If you're not familiar with byte-code, you might read wiki article. 如果您不熟悉字节码,则可以阅读Wiki文章。

Compiler is looking on the type of argument when decide which overloading method to call. 决定调用哪种重载方法时,编译器正在查看参数的类型。 Your type is int . 您的类型是int So, the method signature 所以,方法签名

public void callMtd(int i)

will be used, determined at compile time. 将在编译时确定使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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