Java中为什么不同的返回类型不算方法重载

 更新时间:2022年05月11日 17:20:32   作者:​ Java中文社群   ​  
这篇文章主要介绍了Java中为什么不同的返回类型不算方法重载,方法重载是指在同一个类中,定义了多个同名方法,但每个方法的参数类型或者是参数个数不同就是方法重载,下文详细介绍,需要的小伙伴可以参考一下

方法重载是指在同一个类中,定义了多个同名方法,但每个方法的参数类型或者是参数个数不同就是方法重载。 比如以下 4 个 method 方法就可以称之为方法重载,

如下代码所示:

public class OverloadExample {
    public void method() {
        // doSomething
    }
    public void method(String name) {
        // doSomething
    }
    public void method(Integer id) {
        // doSomething
    }
    public void method(Integer id, String name) {
        // doSomething
    }
}

为什么不同返回类型不算方法重载?

要回答这个问题,首先要了解一点前置内容,方法签名。 方法签名是由:方法名称 + 参数类型 + 参数个数组成的一个唯一值,这个唯一值就是方法签名,而 JVM(Java 虚拟机)就是通过这个方法签名来决定调用哪个方法的。 从方法签名的组成规则我们可以看出,方法的返回类型不是方法签名的组成部分,所以当同一个类中出现了多个方法名和参数相同,但返回值类型不同的方法时,JVM 就没办法通过方法签名来判断到底要调用哪个方法了,如下图所示: 

那为什么返回类型不能做为方法签名的一部分呢? 原因其实很简单,试想一下,如果方法的返回类型也作为方法签名的一部分,那么当程序员写了一个代码去调用“重载”的方法时,JVM 就不能分辨要调用哪个方法了,

如下代码所示:

public class OverloadExample {
    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        example.method("磊哥"); // JVM 应该调用哪个方法?
    }
    public int method(String name) {
        // doSomething
        return 666;
    }
    public String method(String name) {
        // doSomething
        return "磊哥聊编程";
    }
}

像以上情况,JVM 就推断不出来要调用哪个方法了,所以方法的返回类型不能作为方法签名的一部分。

方法重载的使用场景

方法重载的经典使用场景是 String 类型的 valueOf 方法,valueOf 方法重载有 9 种实现,

如下图所示: 

 它可以将数组、对象和基础数据类型转换成字符串类型。

方法重载匹配原则

方法重载的调用顺序是有前后之分的,比如以下代码:

public class OverloadExample {
    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        example.method(12);
    }
    public void method(int num) {
        System.out.println("调用 int 方法");
    }
    public void method(long num) {
        System.out.println("调用 long 方法");
    }
    public void method(Integer num) {
        System.out.println("调用 Integer 方法");
    }
    public void method(Object num) { 
        System.out.println("调用 Object 方法");
    }
    public void method(int... num) { // 可选参数
        System.out.println("调用 int... 方法");
    }
}

当出现方法重载时,程序要调用哪个方法呢?执行以上程序的执行结果如下: 

 因此我们可以得出以下结论。

匹配原则1:精准类型匹配

方法重载会优先调用和方法参数类型一模一样的方法,这是第一优先匹配原则:精准类型匹配

匹配原则2:基本类型自动转换成更大的基本类型

接下来我们把精准匹配方法删掉,观察一下第二匹配顺序是什么?

实现代码如下:

public class OverloadExample {
    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        example.method(12);
    }
    public void method(long num) {
        System.out.println("调用 long 方法");
    }
    public void method(Integer num) {
        System.out.println("调用 Integer 方法");
    }
    public void method(Object num) { 
        System.out.println("调用 Object 方法");
    }
    public void method(int... num) { // 可选参数
        System.out.println("调用 int... 方法");
    }
}

以上程序的执行结果如下图所示: 

 因此我们可以得出结论:如果是基本数据类型,那么方法重载调用的第二匹配原则是自动转换成更大的基本数据类型

匹配原则3:自动装/拆箱匹配

接下来将第二匹配原则中的 long 方法也删除掉,实现代码如下:

public class OverloadExample {
    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        example.method(12);
    }
    public void method(Integer num) {
        System.out.println("调用 Integer 方法");
    }
    public void method(Object num) {
        System.out.println("调用 Object 方法");
    }
    public void method(int... num) { // 可选参数
        System.out.println("调用 int... 方法");
    }
}

以上程序的执行结果如下图所示: 

 从上述执行结果可以看出,方法重载的第三匹配原则是,匹配自动装箱或拆箱的数据类型

匹配原则4:按照继承路线依次向上匹配

此时将第三匹配原则中的 Integer 方法删除,剩下代码如下:

public class OverloadExample {
    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        example.method(12);
    }
    public void method(Object num) {
        System.out.println("调用 Object 方法");
    }
    public void method(int... num) { // 可选参数
        System.out.println("调用 int... 方法");
    }
}

以上程序的执行结果如下图所示: 

 从上述执行结果可以看出,方法重载的第四匹配原则是,依次向上匹配父类的方法调用

匹配原则5:可变参数匹配

最后将代码中的方法删除的只剩一个可选参数,实现代码如下:

public class OverloadExample {
    public static void main(String[] args) {
        OverloadExample example = new OverloadExample();
        example.method(12);
    }
    public void method(int... num) { // 可选参数
        System.out.println("调用 int... 方法");
    }
}

以上程序的执行结果如下图所示: 

 从上述执行结果可以看出,方法重载的第五匹配原则是,匹配可选参数。

总结

在同一个类中定义了多个同名方法,但每个方法的参数类型或者是参数个数不同就是方法重载。方法重载的典型使用场景是 String 中的 valueOf 方法,它有 9 种实现。方法返回类型不能作为方法重载的依据,因为它不是方法签名的组成部分。方法重载有 5 个匹配原则:精准匹配、基本类型自动转换成更大的基本类型匹配、自动装/拆箱匹配、按照继承路线依次向上匹配、可变参数匹配。

到此这篇关于Java中为什么不同的返回类型不算方法重载的文章就介绍到这了,更多相关Java返回类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java使用JDBC连接postgresql数据库示例

    Java使用JDBC连接postgresql数据库示例

    这篇文章主要介绍了Java使用JDBC连接postgresql数据库,结合实例形式分析了jdbc连接postgresql数据库及数值插入、更新、查询等相关操作技巧,需要的朋友可以参考下
    2019-01-01
  • Springboot安全框架整合SpringSecurity实现方式

    Springboot安全框架整合SpringSecurity实现方式

    这篇文章主要介绍了Spring全家桶中Springboot安全框架整合SpringSecurity的实现方式,有需要的朋友可以借鉴参考下,希望可以有所帮助
    2021-09-09
  • spring使用ehcache实现页面缓存示例

    spring使用ehcache实现页面缓存示例

    这篇文章主要介绍了spring使用ehcache实现页面缓存示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Java实现的图像查看器完整实例

    Java实现的图像查看器完整实例

    这篇文章主要介绍了Java实现的图像查看器,以完整实例形式较为详细的分析了java处理图片的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-10-10
  • springboot + JPA 配置双数据源实战

    springboot + JPA 配置双数据源实战

    这篇文章主要介绍了springboot + JPA 配置双数据源实战,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Java实现解析并生成xml原理实例详解

    Java实现解析并生成xml原理实例详解

    这篇文章主要介绍了Java实现解析并生成xml原理实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java线程优先级和守护线程原理解析

    Java线程优先级和守护线程原理解析

    这篇文章主要介绍了Java线程优先级和守护线程原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java中的关键字_动力节点Java学院整理

    Java中的关键字_动力节点Java学院整理

    关键字也称为保留字,是指Java语言中规定了特定含义的标示符。对于保留字,用户只能按照系统规定的方式使用,不能自行定义
    2017-04-04
  • Hystrix Turbine聚合监控的实现详解

    Hystrix Turbine聚合监控的实现详解

    微服务架构下,⼀个微服务往往部署多个实例,如果每次只能查看单个实例的监控,就需要经常切换很不⽅便,在这样的场景下,我们可以使⽤ Hystrix Turbine 进⾏聚合监控,它可以把相关微服务的监控数据聚合在⼀起,便于查看
    2022-09-09
  • 带你入门java雪花算法原理

    带你入门java雪花算法原理

    SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。在分布式系统中的应用十分广泛,且ID 引入了时间戳,基本上保持自增的
    2021-06-06

最新评论