java调用方法选择机制

姜小白- 2014-09-26 08:32:44
前两天看到的问题,有一点自己的看法,怕理解有误,还是拿出来跟大家探讨探讨。

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

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); 调用的是上面的哪个方法,为什么?
...全文
496 15 打赏 收藏 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
ydarin 2014-10-02
  • 打赏
  • 举报
回复
学习了,长见识了
Kifile 2014-10-02
  • 打赏
  • 举报
回复
引用 13 楼 u010342936 的回复:
首先,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。
点赞,这个解释结合上面说如果同时有 String,int[]看得话,觉得很对
全小范 2014-10-02
  • 打赏
  • 举报
回复
首先,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。
yqj2065 2014-10-01
  • 打赏
  • 举报
回复
引用 3 楼 Android_iPhone 的回复:
感觉这样的语言细节了解的越多越好 不是钻牛角尖儿,而是加深理解

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
神奇
yqj2065 2014-10-01
  • 打赏
  • 举报
回复
能够调用的方法不止一个时,逐一作出判断:如果一个方法的类型签名都可以赋值给另一个方法,则后者(类型大者)被排除;重复此操作,直到无法排除为止。 所以,...
Yang_outlook 2014-09-29
  • 打赏
  • 举报
回复
竟然是第二个 magic。。。
人_生而伟大 2014-09-29
  • 打赏
  • 举报
回复
java程序在运行时,当遇到函数重载的时候,会根据参数去匹配最接近的子类,然后再去匹配父类,Object是所有子类的父类,所以最后考虑翻书为Object的方法的执行。
  • 打赏
  • 举报
回复
谢谢各位的分享,好东西
姜小白- 2014-09-27
  • 打赏
  • 举报
回复
引用 6 楼 u011461314 的回复:
只能说明null是对象。 先找具体对象。 这样就报错了,有2个具体对象,不知道匹配谁。 String int[]
恩 null 是现象级的

String a1 = null;
System.out.println(a1 + "a2");
不过,确实值得一看。感觉比较好玩,就拿出来探讨下
zhjdg 2014-09-27
  • 打赏
  • 举报
回复
只能说明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");
	}
skyWalker_ONLY 2014-09-27
  • 打赏
  • 举报
回复
竟然是第二方法,好神奇。我觉得跟方法加载顺序是否有关系
jacob_cxt 2014-09-27
  • 打赏
  • 举报
回复
method1 实际运行发现真错了 太难了 得看看源码到底是如果匹配参数的 难道是先子类后父类, 先基本类型后引用类型的顺序吗?
日知己所无 2014-09-27
  • 打赏
  • 举报
回复
感觉这样的语言细节了解的越多越好 不是钻牛角尖儿,而是加深理解

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
姜小白- 2014-09-26
  • 打赏
  • 举报
回复
引用 1 楼 Android_iPhone 的回复:

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");
    }
}
嘿嘿
这是另外一种情况 我在想 是不是钻牛角尖了
日知己所无 2014-09-26
  • 打赏
  • 举报
回复

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

62,620

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧