java关于重载带来的难题—方法匹配

首先让我们来看一个例子(以下的输出结果基于jdk6版本):

class EasyOver 
{
	static void go(int x){
		System.out.println("int ");
	}
	static void go(long x){
		System.out.println("long ");
	}
	static void go(double x){
		System.out.println("double ");
	}
	public static void main(String[] args) 
	{
		byte b = 5;
		short s = 5;
		long l = 5;
		float f = 5.0f;

		go(b);
		go(s);
		go(l);
		go(f);
	}
}

对于上面的调用将会产生什么样的输出呢?相信对重载有一点了解的人可以很轻松的就写出输出结果:

int
int
long
double

这种结果我们一看就知道了,并且也不是那么令人惊讶,应为使用byte和short变元的调用被隐式加宽,以匹配带int的go()方法的版本,当然带long变元的调用会使用go()方法的long版本,最后,是用float变元的调用会与带double变元的方法匹配。

但是对于如下的带有装箱变元的go方法呢?

class AddBoxing{
	static void go(Integer x){
		System.out.println("Integer ");
	}
	static void go(long x){
		System.out.println("long");
	}

	public static void main(String args[]){
		int i = 4;
		go(i);
	}
}

对于如上的代码将会产生怎样的输出呢?是Integer还是long呢?

正如我们所理解的那样,如果只存在go()方法的Integer变元,那么毫无疑问,java5的装箱能力将允许调用成功从而输出Integer;同样仅当long版本存在时,编译器将使用它处理go()方法调用,也就是会输出long,但是两个方法都存在,就像上面那样,编译器会使用哪个方法呢?

答案是:编译器将选择加宽而不是装箱,因此输出将是:

long
对于上面的结果,相信很多读者和我最初一样也有疑问,为什么呢???

对于这个问题,根据java5的设计者的解释是:最重要的规则应该是已有代码应该像他们过去那样运行,因此,既然加宽能力已经存在,通过加宽调用的方法不应该输给新创建的依赖于装箱的方法,基于这种规则,请预测下如下输出:

class AddVarargs{
	static void go(int x,int y){
		System.out.println("int,int");
	}
	static void go(byte... x){
		System.out.println("byte...");
	}
	public static void main(String args[]){
		byte b = 5;
		go(b,b);
	}
}


相信聪明的你已经猜到输出是:

int,int

确实如你所想,即使每个调用都要求某种转换,在选择较新的风格之前,编译器仍将倾向于优先选择较老的风格,以保持现有代码的健壮性。

到这我们已经知道:

      1、 加宽将优于装箱先执行

      2、加宽优于var-arg(可变变元方法)执行

那么var-arg和装箱呢?请看下面的代码:

class BoxOrVararg 
{
	static void go(Byte x,Byte y){
		System.out.println("Byte,Byte");
	}
	static void go(byte... x){
		System.out.println("byte...");
	}
	public static void main(String[] args) 
	{
		byte b = 4;
		go(b,b);
	}
}

上面的结果将是什么呢?在这我就不说了,留给读者自己探索吧


另外,对于与基本数据类型对应的包装器类型之间是否也是这样的规律呢?

关于重载,还有几点比较重要,这篇就写到这了,我会在下一篇中继续介绍,欢迎大家来一起学习!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值