本文已收录《Java常见面试题》:https://gitee.com/mydb/interview

方法重载是指在同一个类中,定义了多个同名方法,但每个方法的参数类型或者是参数个数不同就是方法重载。

比如以下 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中为什么不同的返回类型不算方法重载?的更多相关文章

  1. java中相同名字不同返回类型的方法

    这种名字相同返回类型不同的方法,在同一个类中是无法共存的,不论是继承过来的方法,还是多实现过来的方法,在一个类内都无法共存.名字确定了,你能改的只有参数(重载).

  2. (转) Java中的负数及基本类型的转型详解

    (转) https://my.oschina.net/joymufeng/blog/139952 面这行代码的输出是什么? 下面两行代码的输出相同吗? 请尝试在Eclipse中运行上面的两个代码片段, ...

  3. 【转】java中byte数组与int类型的转换(两种方式)----不错

    原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法, ...

  4. java中读取特殊文件的类型

    java中读取特殊文件的类型: 第一种方法(字符拼接读取): public static String getType(String s){ String s1=s.substring(s.index ...

  5. Java中的基本类型和包装类型区别

    首先看一下几个测试题,验证一下java中对基本类型和包装类型的理解,看看最后输出的答案对不对,答案在这篇博客中哦: // 第一题: 基本类型和包装类型 int a = 100; Integer b = ...

  6. Java中的两种异常类型及其区别?

    Java中的两种异常类型是什么?他们有什么区别? Throwable包含了错误(Error)和异常(Excetion两类) Exception又包含了运行时异常(RuntimeException, 又 ...

  7. JAVA中如何获取变量的类型

    JAVA中如何获取变量的类型? package xiya; public class Demo { public static void main(String[] args) { String ty ...

  8. java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换

    java中如何理解:其他类型 + string 与 自增类型转换和赋值类型转换 一.字符串与其他类型连接 public class DemoString{ public static void mai ...

  9. Java执行shell脚本并返回结果两种方法的完整代码

    Java执行shell脚本并返回结果两种方法的完整代码 简单的是直接传入String字符串,这种不能执行echo 或者需要调用其他进程的命令(比如调用postfix发送邮件命令就不起作用) 执行复杂的 ...

随机推荐

  1. linux shell中的条件判断语句

    http://bbs.chinaunix.net/thread-396805-1-1.html shell 判断语句 流程控制 "if" 表达式 如果条件为真则执行then后面的部 ...

  2. Linux学习 - 系统命令sudo权限

    1 功能 root把超级用执行的命令赋予普通用户执行 2 使用 visudo 或 vim /etc/sudoers 说明: root 用户名 ALL=(ALL) 被管理主机的地址=(可使用的身份) A ...

  3. GO类型转换

    golang []byte转string golang中,字符切片[]byte转换成string最简单的方式是 package main import ( "fmt" _ &quo ...

  4. 【Java 8】函数式接口(二)—— 四大函数接口介绍

    前言 Java8中函数接口有很多,大概有几十个吧,具体究竟是多少我也数不清,所以一开始看的时候感觉一脸懵逼,不过其实根本没那么复杂,毕竟不应该也没必要把一个东西设计的很复杂. 几个单词 在学习了解之前 ...

  5. mybtis入门

    1.编写持久化对象 public class User { private String id;//用户编号 private String username;//用户名 private String ...

  6. 如何优雅正确地通过interrupt方法中断线程

    为什么废弃Thread的stop函数? 简单来说就是stop方法中断线程太过暴力随意,且会是否线程持有的锁,会导致线程安全问题.还有可能导致存在需要被释放的资源得不到释放,引发内存泄露.所以用stop ...

  7. 30个类手写Spring核心原理之依赖注入功能(3)

    本文节选自<Spring 5核心原理> 在之前的源码分析中我们已经了解到,依赖注入(DI)的入口是getBean()方法,前面的IoC手写部分基本流程已通.先在GPApplicationC ...

  8. mysql深度优化与理解(迄今为止读到最优秀的mysql博客)

    转载:https://www.cnblogs.com/shenzikun1314/p/6396105.html 本篇深入了解查询优化和服务器的内部机制,了解MySql如何执行特定查询,从中也可以知道如 ...

  9. de1ctf_2019_weapon(爆破_IO_2_1_stdout)

    (这是我真正意义上的完完全全自己做的第一道堆题目,虽然花了快三个小时,谨以此篇纪念一下) 题目的例行检查我就不放了,将程序放入ida中 程序的逻辑十分简单,漏洞也非常明显 重点是这个程序没有给我们sh ...

  10. 使用NTP原理进行时间同步

    在一些物联网企业,平台会和嵌入式一起配合进行工作. 有时平台会希望嵌入式这边不使用现成的NTP方案自己去同步时间,而希望以平台下发的时间为准. 此时就有两个方案. 方案1.  平台下发一个时间戳tim ...