通俗易懂的Java方法分派策略

第一时间获取 IT 技术干货!

阅读文本大概需要 4 分钟。

1

基础

我们知道Java有一大特性就是多态。讲到多态不得不想再深层次的研究下多态中的方法分派到底是采用什么样的策略的。

还是举个例子来分析一下:

public class SuperClass {
    public String getName() {
        return "super";
    }
}


public class SubClass extends SuperClass{
    @Override
    public String getName() {
        return "sub";
    }
}


public class MainClass{


    public static void main(String... args) {
        SuperClass superClass = new SubClass();
        test(superClass);
    }
    
    public static void test(SuperClass superClass) {
        System.out.println("a " + superClass.getName());
    }
    
    public static void test(SubClass subClass) {
        System.out.println("b " + subClass.getName());
    }
}

上面的代码中最终输出的应该是多少呢?
别着急,咱们先分析下上面的输出会有什么不同,我们声明的是一个父类对象,但是实例化的时候是以子类来实例化的,所以影响输出结果的第一个问题是:

① getName()方法最后输出的是"super"还是"sub",也就是调用的子类的getName还是父类的getName

第二个问题是:

② test()调用的是第一个以父类为参数的方法还是第二个以子类型为参数的方法

其实对于①问题,稍微有过编程经验的人都清楚,getName肯定是调用的是子类的方法,因为本来就是子类的实例,这也是Java多态的一种体现。

作为一个初级工程师,以上都是应该知道的。

对于第二个问涉及的是Java编译器在将test()编译成字节码的时候,需要知道参数的类型,而参数类型就是你声明变量的类型,也就是说会调用test(SuperClass)方法。所以最后会输出"a sub"。

如果你已经知道这些了,恭喜你中级工程师的水平有了。

稍微总结一下上面的内容,Java的方法分派分为两种:

  1. 静态分派 - 方法重载分派

    1. 编译器就确定

    2. 依据调用者的声明类型和方法的参数类型匹配

  2. 动态分派 - 方法重写分派

    1. 运行时确定

    2. 依据调用者的实际类型分派

2

发散一下

如果你做过Android开发,你一定对Groovy或多或少有一定的了解(我们在写Gradle脚本时就是使用的Groovy语言)。我们也是知道在Groovy中也是可以写Java的代码的,如果将上面的代码放到Groovy中,输出的结果一样吗?

还真不一样,输出的是"b sub",这是Groovy不同之处哈,他在被编译成字节码的时候,test()方法被编译成了CallSite.callStatic方法,而这个方法会在运行时通过反射拿到参数的实际类型,然后决定调用哪个test方法,那实际类型当然是子类了,所以会调用以子类为参数类型的方法了。

到这里,如果你能够触类旁通,不仅仅局限于一种语言,能够多语言横向对比,那么显然你具有了高工的气质了。如果你有兴趣的话,不妨对比下C++、Kotlin、Scala等语言之间有什么区别。

本节内容实际上比较简单直白,但是涉及到的点你平时不一定有认真思考过,只有比较系统的掌握了语言才能对他的编译和运行机制了如指掌。所以只有多思考才能进步。

推荐阅读:

你说你是高工,匿名内部类有我玩得6吗?

你说你是高工,String有多长也不知道?

你说你是高工,char都没搞明白?!

THANDKS

- End -

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值