How JVM finds method (parameter with the closest matching) to call in case of function overloading

梦想与她 提交于 2019-12-21 03:42:21

问题


The JVM decides which overloaded method to call at compile time. I have one example:

public class MainClass{

  public static void go(Long n) {System.out.println("takes Long ");}
  public static void go(Short n) {System.out.println("takes Short ");}
  public static void go(int n) {System.out.println("takes int ");}

  public static void main(String [] args) {
    short y = 6;
    long z = 7;
    go(y);
    go(z);
    go((Short)y);
  }
}

According to my understanding, it should print the following:

takes Short
takes Long
takes Short

... but the actual output is:

takes int
takes Long
takes Short

However if I have the following three functions:

public static void go(Integer n) {System.out.println("takes Integer");}
public static void go(Long n) {System.out.println("takes Long ");}
public static void go(Short n) {System.out.println("takes Short ");}

... and call it using:

int a= 10; and go(i);  //output : takes Integer.

... why there is there a difference for short and int?


回答1:


See JLS Section 15.12.2, for rules compiler follows to determine which method to invoke. Compiler always chooses the most specific method in case your methods are overloaded:

There may be more than one such method, in which case the most specific one is chosen. The descriptor (signature plus return type) of the most specific method is one used at run time to perform the method dispatch.

Compiler first tries to resolve the method without boxing or unboxing as quoted there:

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

Emphasis mine.

So, in your 1st code, since short can be used as argument for parameter of type int. Compiler will not use the method with parameter Short, as that requires boxing. While in case of long type, since it cannot be used as argument for type int, it goes for boxing it to Long. Remember Widening is preferred over Boxing.

In your 2nd, there is no other way than boxing int to Integer. So, it calls method with Integer parameter.




回答2:


The JVM doesn't find it at all. The compiler does. It chooses the most specific method, following the rules in JLS section 15.12.2.5:

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.

The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.

... (full rules) ...




回答3:


Because upcasting to int was in version 1.0 of Java and auto-boxing was added in version 5.0. Changing the behaviour would break code written for older version of Java.




回答4:


Widening happens before boxing (if any). So short will become int and call that methods.

Besides, not directly relevant with this questions but interesting point: You cannot box and widen i.e. short can't become Integer




回答5:


Java looks for the closest match first. It tries to find the following:

  1. Exact match by type
  2. Matching a super class type
  3. Converting to a larger primitive type
  4. Converting to an auto boxed type
  5. Varargs



回答6:


The video below clearly explains the way how the JVM select one method among various eligible methods in the case of method overloading.

https://www.youtube.com/watch?v=P4XtP1aeI3g



来源:https://stackoverflow.com/questions/17999480/how-jvm-finds-method-parameter-with-the-closest-matching-to-call-in-case-of-fu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!