java调用方法取舍机制

java调用方法选择机制
本帖最后由 magi1201 于 2014-09-26 20:38:12 编辑
前两天看到的问题,有一点自己的看法,怕理解有误,还是拿出来跟大家探讨探讨。

代码如下,请问下面的方法调用会执行哪个方法?
请先判断,后执行代码。

public static void main(String[] args) {
invoke(null);
}

// method_1
public static void invoke(Object obj) {
System.out.println("Object obj");
}

// method_2
public static void invoke(int[] arr) {
System.out.println("int[] arr");
}

// method_3
public static void invoke(int num) {
System.out.println("int num");
}

请问 第2行的 invoke(null); 调用的是上面的哪个方法,为什么?

------解决思路----------------------

public class InvokeTest {

    public static void main(String[] args) {
        Object obj = null;
        invoke(obj);
    }

// method_1   
    public static void invoke(Object obj) {
        System.out.println("Object obj");
    }

// method_2   
    public static void invoke(int[] arr) {
        System.out.println("int[] arr");
    }

// method_3   
    public static void invoke(int num) {
        System.out.println("int num");
    }
}


嘿嘿
------解决思路----------------------
感觉这样的语言细节了解的越多越好
不是钻牛角尖儿,而是加深理解


public class Abc {

    public static void main(String[] args) {
        String letters = "ABC";
        char[] numbers = {'1', '2', '3'};
        System.out.println("1)" + letters + " easy as " + numbers);
        System.out.print("2)" + letters + " easy as ");
        System.out.println(numbers); // Invokes println(Object)
    }
}


上面的示例是Java Puzzlers的第12个谜题
Ctrl+A查看运行结果
1)ABC easy as [C@15db9742
2)ABC easy as 123

------解决思路----------------------
只能说明null是对象。
先找具体对象。

这样就报错了,有2个具体对象,不知道匹配谁。   String   int[]

public static void main(String[] args) {
invoke(null);
}

// method_1
public static void invoke(Object obj) {
System.out.println("Object obj");
}

// method_2
public static void invoke(int[] arr) {
System.out.println("int[] arr");
}

// method_3
public static void invoke(int num) {
System.out.println("int num");
}

public static void invoke(String str) {
System.out.println("str");
}

------解决思路----------------------
能够调用的方法不止一个时,逐一作出判断:如果一个方法的类型签名都可以赋值给另一个方法,则后者(类型大者)被排除;重复此操作,直到无法排除为止。
所以,...
------解决思路----------------------
首先,method 3排除。

// method_3
public static void invoke(int num) {

null是空的对象引用。int是基本数据类型,不存在引用的概念。
你可以试一下 
int a = null;

肯定会报错了。

接下来要判断,程序调用的是method 1还是method 2,
就必须了解Java的重载解析过程。

Java的重载解析过程是以下两阶段运行的。

第一阶段 选取所有可获得并且可应用的方法。
     这一阶段,程序选取method 1和method2。排除了method3。

第二阶段在第一阶段选取的方法中选取最精确的一个。
     什么是最精确的一个呢?
     如果一个方可以接受传递给另一个方法的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性。
     

    // method_1   
    public static void invoke(Object obj) {
 
    // method_2   
    public static void invoke(int[] arr) {

    显然invoke(Object obj)的参数,可以接受任何传递给invoke(int[] arr)的参数。因此method 1相对缺乏精确性。
    
    所以,main方法调用的是method 2。