在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 就没办法通过方法签名来判断到底要调用哪个方法了,如下图所示: 

image.png

 那为什么返回类型不能做为方法签名的一部分呢? 原因其实很简单,试想一下,如果方法的返回类型也作为方法签名的一部分,那么当程序员写了一个代码去调用“重载”的方法时,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 种实现,如下图所示: 

image.png

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

方法重载匹配原则

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

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... 方法");
    }
}
复制代码

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

image.png

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

匹配原则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... 方法");
    }
}
复制代码

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

image.png

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

匹配原则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... 方法");
    }
}
复制代码

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

image.png

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

匹配原则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... 方法");
    }
}
复制代码

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

image.png

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

匹配原则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... 方法");
    }
}
复制代码

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

image.png

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

总结

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
重写和重载都是 Java 的重要概念,它们都涉及到方法的定义和使用。 重写(Override)是指在子类定义一个与父类同名、同参数列表、同返回类型方法,并且使用 `@Override` 注解标识。子类方法会覆盖父类的同名方法,实现多态性。重写的方法可以使用 `super` 关键字调用父类的同名方法,也可以不调用。 例如: ```java class Animal { public void move() { System.out.println("动物在移动"); } } class Dog extends Animal { @Override public void move() { System.out.println("狗在奔跑"); } } ``` 上面的代码,`Dog` 类继承自 `Animal` 类,并重写了 `move()` 方法,实现了多态性。 重载(Overload)是指在一个类定义多个同名方法,但是参数列表不同Java 编译器会根据方法的参数列表和返回类型来区分不同方法重载方法可以实现不同类型的参数处理,提高了代码的灵活性和复用性。 例如: ```java class Calculator { public int add(int x, int y) { return x + y; } public double add(double x, double y) { return x + y; } } ``` 上面的代码,`Calculator` 类定义了两个同名方法 `add()`,但是参数列表不同,分别处理整型和浮点型参数。在调用时,Java 编译器会根据实际参数类型来选择调用哪个方法,实现了方法重载。 总之,重写和重载都是 Java 重要的概念,需要根据具体的需求来选择使用哪种方式。重写实现了多态性,重载提高了代码的灵活性和复用性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值