您的位置:首页 > 编程语言 > Java开发

关于java重载(重载方法匹配优先级)

2015-09-17 09:59 441 查看

首先看一段代码

public class Overload {
public static void sayHello(Object arg){
System.out.println("hello object");
}
public static void sayHello(int arg){
System.out.println("hello int");
}
public static void sayHello(char arg){
System.out.println("hello char");
}
public static void sayHello(long arg){
System.out.println("hello long");
}
public static void sayHello(char... arg){
System.out.println("hello char...");
}
public static void sayHello(Character arg){
System.out.println("hello Character");
}
public static void sayHello(Serializable arg){
System.out.println("hello Serializable");
}
public static void main(String[] args) {
Overload.sayHello('a');
}
}
上面代码运行后输出
hello char
这样很好理解,‘a’是一个char类型,自然会寻找参数为char的重载方法,如果注释掉 
sayHello(char arg)方法,那输出会变为:
hello int
这时发生了一次自动类型转换,‘a'除了可以代表一个字符串,还可以代表数字97(字符’a'的Unicode数值为十进制数字的97),因此参数类型为int的重载也是合适的。我们继续注释掉sayHello(int arg)方法,那么输出会变为:
hello long
这时发生了两次自动类型转换,‘a'转型为整数97之后,进一步转型为长整数97L,匹配的参数类型为long的重载。在代码中没有写其他的类型如float、double等重载,不过实际上自动转型还能继续发生多次,按照char->int->long->float->double的顺序进行匹配。但不会匹配到byte和short类型的重载,因为char转byte和short的转型是不安全的。我们继续注释掉sayHello(longarg)方法那么输出会变为:
hello Character
这次发生了一次自动装箱,’a‘被包装为它的封装类型java.long.Character,所以匹配到的参数为Character的重载,继续注释掉sayHello(Character arg)方法,那么输出会变为:
hello Serializable
这个输出可能会让人摸不着头脑,一个字符或数字跟序列化有什么关系?出现hello Serializable,是因为java.long.Serializable是java.long.Character类实现的一个接口,当自动装箱之后发现找不到装箱类,但是找到装箱类实现的接口类型,所以紧接着又发生了一次自动转型。char可以转换成int,但是Character绝不会转换成Interger的,它只会安全的转换成它实现的接口或父类。Character还实现了另外一个接口java.long.Comparable<Serializable>,如果同时出现两个参数分别为Serializable和Comparable<Serializable>的重载方法,那它们在此时的优先级是一样的。编译器无法确定自动转型成哪种类型,会提示类型迷糊,拒绝编译。程序必须在调用时显示的指定字面量的静态类型,如sayHello(Comparable<Serializable>arg),才能编译通过。下面注释掉sayhello(Serializable arg),输出结果变为:
hello object
这是char装箱转型父类了,如果有多个父类,那将在继承关系中从下往上开始搜索,越接近上层的优先级越低,即使调用方法传入参数为null,时,这个规则仍然适用。我们把sayHello(object arg)也注释掉,输出结果将变为:
hello char...
7个重载方法已经被注释得剩一个了,可见边长参数重载的优先级最低。上面的过程演示了编译期间选择静态分配目标的过程,这个过程也是java语言实现重载的本质。这里只是选择了char类型,有兴趣的可以使用其他类型试试。有兴趣的也可以看看《深入理解java虚拟机》这本书,这里讲解的很深入,我也是参考自这本书。有错误还望大家多多指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java