Java重载方法的参数互为父子类时处理策略的探究

本文先对Java重载方法的参数互为父子类时的处理策略进行了查证,后续对涉及到加入重写后的处理策略进行了进一步的探究。

1.起因

老师提出了这样一个问题:
类A中有两个overload方法:
void B(Object o)
void B(Number n)
客户端程序
new A().B(Integer.valueOf(1))调用的是哪个B方法?还是说这段代码无法通过编译?

2.运行结果及原因

在这里插入图片描述
        粗略完成后运行结果如上图,调用了参数为Number n的方法。原因其实很简单,Object类是所有类的父类,而Number类又是Byte, Double, Float, Integer, Long, Short等类的父类。在上述程序中,主程序传入的参数为Integer.valueOf(1)的返回值,也就是Integer类型,三者的关系为Object→Number→Integer。A().B(Integer.valueOf(1))在class A中没有找到类型匹配的方法,这时触发了Java自动类型提升机制,对Integer进行向上转型后匹配到了了public void B(Number n) 方法,调用后输出字符串"Num".
        我们用String类进行测试,符合预期,如下左图。而如果方法参数中没有String类或它的父类,则会在静态检查阶段提示错误,如下右图。

3.再探究

        如果给你如下代码,你认为运行后在控制台的输出结果是什么呢?
        有小伙伴答案和我最初一样是下面三句的吗?
                Obj from C
                Num from C
                Str fromA
        它的最终输出实际是
                Obj from C
                Obj from C
                Str fromA

package one;
class A {
    
    
	public void B(Object o) {
    
    
		System.out.println("Obj from A");
	}
	public void B(String o) {
    
    
		System.out.println("Str from A");
	}
}
class C extends A{
    
    
	public void B(Object o) {
    
    
		System.out.println("Obj from C");
	}

	public void B(Number n) {
    
    
		System.out.println("Num from C");
	}
}
public class Test{
    
    
	public static void main(String[] args) {
    
    
		Object t1 = null;
		Number t2 = null;
		String t3 = null;
		A a=new C();
		a.B(t1);
		a.B(t2);
		a.B(t3);
	}
}

        产生这样结果的原因是这里 a 的引用类型是 class A,但是它指向的内存是类型为 class C 的一个实例。对a进行方法调用时,调用的方法必须是类A里存在的方法,如果上述代码中删去类A里的方法public void B(Object o),那么a.B(t1); a.B(t2);两个语句都会像上张图出现静态检测错误。
        Java 执行方法时,是动态匹配的,在运行时才会决定用哪个方法。我们分析a.B(t2),首先它并没有在class A中找到参数类型为Number的方法,于是对Number进行向上转型,发现与A中的public void B(Object o)匹配成功。但是a指向的是class C的内存空间,而C中对public void B(Object o)方法进行了Override,所以最后动态链接调用了类C中方法输出"Obj from C".这里我引用查证时看到的前辈的说法:
        Overload 是由编译器在编译时决定的,因为 a 的声明类型为 A,所以会调用 class A中 public void B(Object o) 方法,编译类型一致。
        Override 是多态,由运行时实际类决定,所以调用的是class C的方法而不是class A的方法。
        这样 t2 和 t3 的执行结果都很好解释,不再赘述。

以上为授课老师提出问题后思考查证的结果,若有错误,敬请斧正。

猜你喜欢

转载自blog.csdn.net/weixin_45630209/article/details/105666003