本文已收录《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 面试真题解析