纳尼?Java种的重载还有静态绑定这种说法?

流量如水,文章就是一个瓶子,标题是瓶口,内容是瓶身。 瓶子装水有多快依赖瓶口大小,瓶子装水有多少依赖瓶身大小。

什么是重载?

在同一个类中,如果多个方法有相同的方法名称,不同的参数类型,参数个数,参数顺序,即称为重载,比如一个类中有多个构造方法。
String 类中的 valueOf 是比较著名的重载案例,它有9个方法,可以将输入的基本数据类型、数组、Object 等转化称为字符串。在编译器的眼里,方法名称+参数列表,组成了一个唯一键,称为方法签名,JVM 通过这个唯一键决定调用哪种重载的方法。注意,方法返回值并非是这个组合体中的一员,所以在使用重载机制时,不能有两个方法名称完全相同,参数类型和个数也相同,但是返回类型不相同的方法,如下实例代码:

public class Student {
	public void methodOverload() {}

	// 编译出错,返回值并不是方法签名的一部分
	public int methodOverload() {
		return 7;
	}
	
	// 编译出错,访问修饰符也不是方法签名的一部分
	private void methodOverload() {}

	// 编译出错,final 修饰符也不是方法签名的一部分
	private final void methodOverload() {}

	// 编译出错,static 修饰符也不是方法签名的一部分
	public static void methodOverload() {}
}

重载的调用规则是什么?

重载似乎是比较容易理解和掌握的编程技能了,有时候仅仅凭借肉眼就能知道应调用哪个重载方法,那么看如下实例代码,如果调用 methodOverload(7) ,猜一下到底调用的是谁呢(JDK11 环境)?

public class OverloadMethods {
	// 1.无参方法
	public void methodOverload() {
		System.out.println("无参方法");
	}

	// 2.基本数据类型
	public void methodOverload(int param) {
		System.out.println("参数为基本类型 int 的方法");
	}

	// 3.包装数据类型
	public void methodOverload(Integer param) {
		System.out.println("参数为包装类型 Integer 的方法");
	}

	// 4.可变参数,可以接受 0 ~ n 个 Integer 对象
	public void methodOverload(Integer param) {
		System.out.println("可变参数方法");
	}

	// 5.Object 对象
	public void methodOverload(Object param) {
		System.out.println("参数为 Object 的方法");
	}
}

JVM 在重载方法中,选择合适的目标方法的顺序如下:

  • 精确匹配
  • 如果是基本数据类型,自动转换为更大表示范围的基本类型
  • 通过自动拆箱与装箱
  • 通过子类向上转型继承路线依次匹配
  • 通过可变参数匹配

精确匹配优先,这是无容置疑的,int 在和 Integer 的较量中胜出,因为不需要自动装箱,所以 7 会调用 int 参数的方法。也就是第2种方法,你猜对了吗?如果是 new Integer(7) 的话,Integer 参数的方法胜出。
如果本方法只有 methodOverload(long) ,则可以接收 methodOverload(3) 的实参调用;反之,如果只有 methodOverload(int) ,而传入 long 值,则会编译出错。基本数据类型转化为表示范围更大的基本数据类型优先于自动装箱,即 int 转为 long ,优先于装箱为 Integer ,所以会发生编译错误。
注意,null 可以匹配任何类对象,在查找目标方法时,是从最底层子类依次向上查找的,在本次实例中,如果 methodOverload(null) ,则会调用参数为 Integer 的方法。为什么呢?

1. 因为 Integer 是一个类
2. 它是 Object 的子类

在示例代码中,如果还有单个 String 类型参数的方法,则会编译出错,因为 null 不知道该选择 Integer 还是 String。根据上述规则,可变参数的优先级别是最低的,但是如果调用 methodOverload(13,14) ,此时有两个参数,虽然有自动装箱的开销,但可变参数仍然会执行这种方法请求。

父类的共有实例方法与子类的共有实例方法可以存在重载关系。不管继承关系如何复杂,重载在编译时可以根据规则知道调用哪种目标方法。所以,重载又称为静态绑定。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值