Overloaded method selection based on the parameter's real type

后端 未结 7 1341
悲哀的现实
悲哀的现实 2020-11-22 01:39

I\'m experimenting with this code:

interface Callee {
    public void foo(Object o);
    public void foo(String s);
    public void foo(Integer i);
}

class          


        
相关标签:
7条回答
  • 2020-11-22 02:38

    As mentioned before overloading resolution is performed at compile time.

    Java Puzzlers has a nice example for that:

    Puzzle 46: The Case of the Confusing Constructor

    This puzzle presents you with two Confusing constructors. The main method invokes a constructor, but which one? The program's output depends on the answer. What does the program print, or is it even legal?

    public class Confusing {
    
        private Confusing(Object o) {
            System.out.println("Object");
        }
    
        private Confusing(double[] dArray) {
            System.out.println("double array");
        }
    
        public static void main(String[] args) {
            new Confusing(null);
        }
    }
    

    Solution 46: Case of the Confusing Constructor

    ... Java's overload resolution process operates in two phases. The first phase selects all the methods or constructors that are accessible and applicable. The second phase selects the most specific of the methods or constructors selected in the first phase. One method or constructor is less specific than another if it can accept any parameters passed to the other [JLS 15.12.2.5].

    In our program, both constructors are accessible and applicable. The constructor Confusing(Object) accepts any parameter passed to Confusing(double[]), so Confusing(Object) is less specific. (Every double array is an Object, but not every Object is a double array.) The most specific constructor is therefore Confusing(double[]), which explains the program's output.

    This behavior makes sense if you pass a value of type double[]; it is counterintuitive if you pass null. The key to understanding this puzzle is that the test for which method or constructor is most specific does not use the actual parameters: the parameters appearing in the invocation. They are used only to determine which overloadings are applicable. Once the compiler determines which overloadings are applicable and accessible, it selects the most specific overloading, using only the formal parameters: the parameters appearing in the declaration.

    To invoke the Confusing(Object) constructor with a null parameter, write new Confusing((Object)null). This ensures that only Confusing(Object) is applicable. More generally, to force the compiler to select a specific overloading, cast actual parameters to the declared types of the formal parameters.

    0 讨论(0)
提交回复
热议问题