首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >千万别告诉别人,这是我从高工那偷听来的Java方法分派策略

千万别告诉别人,这是我从高工那偷听来的Java方法分派策略

作者头像
吴延宝
发布2019-12-19 11:28:43
3150
发布2019-12-19 11:28:43
举报

阅读文本大概需要 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等语言之间有什么区别。

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT烂笔头 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档