写出以下程序的输出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public
class
Overload {
public
static
void
say(
long
arg) {
System.out.println(
"hello long"
);
}
public
static
void
say(Character arg) {
System.out.println(
"hello character"
);
}
public
static
void
say(
char
... arg) {
System.out.println(
"hello char..."
);
}
// Serializable 参数
public
static
void
say(Serializable arg) {
System.out.println(
"hello serializable"
);
}
public
static
void
main(String[] args) {
say(
'a'
);
}
}
|
这条题目考的是重载方法匹配的优先级,那么它的匹配优先级是怎样的呢?
我们可以扩充一下这个程序,加入一些其他的参数,然后测试一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
public
class
Overload {
// Object 参数
public
static
void
say(Object arg) {
System.out.println(
"hello object"
);
}
// int 参数
public
static
void
say(
int
arg) {
System.out.println(
"hello int"
);
}
// long 参数
public
static
void
say(
long
arg) {
System.out.println(
"hello long"
);
}
// char 参数
public
static
void
say(
char
arg) {
System.out.println(
"hello char"
);
}
// Character 参数
public
static
void
say(Character arg) {
System.out.println(
"hello character"
);
}
// 变长参数
public
static
void
say(
char
... arg) {
System.out.println(
"hello char..."
);
}
// Serializable 参数
public
static
void
say(Serializable arg) {
System.out.println(
"hello serializable"
);
}
public
static
void
main(String[] args) {
say(
'a'
);
}
}
|
如果将char参数的函数注释之后,会输出什么呢?
答案是:hello int
因为这期间,字符a发生了一次自动转型,它除了能够表示字符a外,还能表示数字65,于是重载方法匹配了int参数的重载方法。
现在我们再将这个方法注释了,输出的结果大家应该知道是什么了吧?
那就是:hello long
原因就是int自动转型为long。其实还可以转化为float和double的,但不能转化为byte和short,因为char到这两个类型的转化是不安全的,这几个类型的转化优先级为:char->int->long->float->double。
好,我们再继续注释掉这个函数,然后输出是什么呢?
答案:hello character
为什么?大家应该知道Java里面为每种基本数据类型都提供一种封装类型吧?char对应的就是Character,所以调用函数期间,当找不到基本类型转化的匹配之后,char就会发生一次自动装箱,变成了Character类型。
根本停不下来啊,再继续注释了它,看下输出。
输出:hello serializable
这什么东西嘛。。。怎么会输出这个家伙啊。。。。原来是因为Character实现了Serializable接口,当它找不到匹配的类型之后,就会找它所实现的接口。但是,如果我们再增加一个重载函数:
1
2
3
|
public
static
void
say(Comparable arg) {
System.out.println(
"hello Comparable"
);
}
|
好,继续注释掉Serializable参数的函数,看输出:hello object
接口找不到匹配之后,就会开始找匹配的父类,优先级是顺着继承链,由下往上进行匹配。
最后,连这个函数也注释了的话,大家应该知道输出的是什么了吧?
当然就是:hello char...
由此可见,变长参数的优先级是最低的。