当前位置: 首页 > 后端技术 > Java

面试官:为什么不同的返回类型不算方法重载?

时间:2023-04-01 18:18:31 Java

本文已收录《Java常见面试题》:https://gitee.com/mydb/interview方法重载是指在同一个类中定义了多个同名方法,但是方法的参数类型或者参数个数每个方法一个不同的数字是方法重载。例如下面四种method方法都可以调用方法重载,如下代码所示:(Integerid){//doSomething}publicvoidmethod(Integerid,Stringname){//doSomething}}为什么不同的返回类型不算方法重载?要回答这个问题,首先要了解一点前置内容,方法签名。方法签名是一个唯一值,由:方法名+参数类型+参数个数组成。这个唯一值就是方法签名,JVM(JavaVirtualMachine)通过这个方法签名来决定调用哪个方法。从方法签名的组成规则可以看出,方法的返回类型并不是方法签名的组成部分,所以当同一个方法中有多个方法名和参数相同但返回值类型不同的方法时类,JVM没有办法使用方法签名来决定调用哪个方法,如下图:为什么返回类型不能是方法签名的一部分?原因其实很简单。试想一下,如果方法的返回类型也是方法签名的一部分,那么当程序员编写代码调用“重载”的方法时,JVM将无法分辨调用哪个方法。如下代码所示:publicclassOverloadExample{publicstaticvoidmain(String[]args){OverloadExampleexample=newOverloadExample();example.method("雷格");//JVM应该调用哪个方法?}publicintmethod(Stringname){//doSomethingreturn666;}publicStringmethod(Stringname){//doSomethingreturn"雷哥聊编程";}}在上述情况下,JVM无法推断调用哪个方法,因此方法的返回类型不能作为方法签名的一部分。方法重载的使用场景方法重载的经典使用场景是String类型的valueOf方法。valueOf方法重载的实现有9种,如下图所示:它可以将数组、对象和基本数据类型转换成字符串类型。方法重载匹配原则方法重载的调用顺序不同,比如下面的代码:publicclassOverloadExample{publicstaticvoidmain(String[]args){例子.方法(12);}publicvoidmethod(intnum){System.out.println("调用int方法");}publicvoidmethod(longnum){System.out.println("calllongmethod");}publicvoidmethod(Integernum){System.out.println("CallIntegermethod");}publicvoidmethod(Objectnum){System.out.println("CallObjectmethod");}publicvoidmethod(int...num){//可选参数System.out.println("Callint...method");}}当发生方法重载时,程序应该调用哪个方法呢?执行上述程序的执行结果如下:因此,我们可以得出以下结论。匹配原则一:类型精确匹配方法重载会优先调用与方法参数类型相同的方法。这就是第一优先匹配原则:精确类型匹配。匹配原则2:基本类型自动转换成更大的基本类型接下来我们去掉精确匹配的方式,观察第二个匹配顺序是什么?实现代码如下:publicclassOverloadExample{publicstaticvoidmain(String[]args){例子.方法(12);}publicvoidmethod(longnum){System.out.println("调用long方法");}publicvoidmethod(Integernum){System.out.println("调用Integer方法");}publicvoidmethod(Objectnum){System.out.println("调用对象方法");}publicvoidmethod(int...num){//可选参数System.out.println("callint...method");}}上面程序的执行结果如下图所示:所以我们可以得出结论:如果是基本数据类型,那么方法重载调用的第二个匹配原则就是自动转换为更大的基本数据类型.匹配原则三:自动装箱/拆箱匹配接下来将匹配原则二中的long方法删掉,实现代码如下:publicclassOverloadExample{publicstaticvoidmain(String[]args){);例子.方法(12);}publicvoidmethod(Integernum){System.out.println("调用Integer方法");}publicvoidmethod(Objectnum){System.out.println("调用对象方法");}publicvoidmethod(int...num){//可选参数System.out.println("callint...method");}}上面程序的执行结果如下图所示:从上面的执行结果可以看出,方法重载的第三个匹配原则是匹配自动装箱或拆箱的数据类型。匹配原则4:按照继承路线向上匹配。这时候把第三条匹配原则中的Integer方法删掉,剩下的代码如下:publicclassOverloadExample{publicstaticvoidmain(String[]args){例子.方法(12);}publicvoidmethod(Objectnum){System.out.println("CallObjectmethod");}publicvoidmethod(int...num){//可选参数System.out.println("callint...method");}}上面程序的执行结果如下图所示:从上面的执行结果可以看出,方法重载的第四个匹配原则是匹配父类的方法依次传递。匹配原则5:可变参数匹配最后把代码中的方法删掉,只剩下一个可选参数。实现代码如下:publicclassOverloadExample{publicstaticvoidmain(String[]args){例子.方法(12);}publicvoidmethod(int...num){//可选参数System.out.println("callint...method");}}上面程序的执行结果如下图所示例子:从上面的执行结果可以看出,方法重载的第五条匹配原则是匹配可选参数。综上所述,同一个类中定义了多个同名方法,但每个方法的参数类型或参数个数不同,这就是方法重载。方法重载的典型使用场景是String中的valueOf方法,它有9种实现。方法返回类型不能用作方法重载的基础,因为它不是方法签名的组成部分。方法重载的匹配原则有5条:精确匹配、基本类型自动转换为更大的基本类型、自动装箱/拆箱匹配、根据继承路由向上匹配、可变参数匹配。参考资料:《码出高效》判断是非自己,听别人说,得失看数字。公众号:Java面试真题解析