“你好,阿米戈!几天前,我跟你说过关重载方法。你都懂了吗?”
“嗯。我记得。每个类的方法必须唯一。如果类不包含同名和同种参数类型的其他方法(参数的顺序很重要),那它的方法就是唯一的。”
“非常好。我看你也学过那课了。今天,我想稍微扩展一下这个主题的知识面。你认为每种情况下会调用哪种方法?”
class Cat
{
public static void print(int n)
{
System.out.println(n);
}
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void print(String s)
{
System.out.println(s);
}
public static void main(String[] args)
{
Cat.print(1);
Cat.print((byte)1);
Cat.print("1");
Cat.print(null);
}
}
“难说。”
“在第一种情况下,1 是 int。我们有个完全匹配的方法带 int。此时会调用第一个 void print(int n)。
在第二种情况下,我们没有带 byte 的方法。但有两个方法分别带 short 和 int。在类型拓宽规则基础上,byte 会首先拓宽为 short,然后拓宽为 int。因此,判定会调用 void print(short n)。
在第三种情况下,我们有一个完全匹配的方法带 String。此时会调用 void print(String s)。
第四种情况是模棱两可的。null 没有特定类型。编译程序将拒绝编译这个代码。在这种情况下,我们要编写 Cat.print((Integer)null) 来调用第三个方法,并且用 Cat.print((String)null) 来调用第四个方法。”
“非常有借鉴意义。谢谢你。”
“我想说的是,在确定正确的调用方法时,类型只能拓宽。它们不能缩小。不妨看这个例子:”
class Cat
{
public static void print(short n)
{
System.out.println(n);
}
public static void print(Integer n)
{
System.out.println(n);
}
public static void main(String[] args)
{
Cat.print((byte)1);
Cat.print(1);
}
}
在第一种情况下,byte 类型将拓宽为 short 类型,第一种方法将被调用:void print(short n)。
在第二种情况下,将进行从 int 到 Integer 的隐式加宽拓宽转换,然后将调用第二种方法:void print(Integer n)。
“没想到。”
“不,这是真正的惊喜:”
Java 语言代码 | 说明 |
---|---|
|
在第一种情况下,int 将扩展为 Integer。因为没有 Integer 的方法,所以最合适的方法(以及调用的方法)是 void print(Object o)
在第二种情况下,不会有任何编译错误,并且将调用 void print(Object o),这个不是特别明明显。 |
“阿米戈,我希望你理解在这种情况下,最好指定类型转换运算符(就像我们对“(byte)”所做的那样),以便确切地知道将调用哪种方法。”
“我从没想到重载方法会出现任何问题。但是后来你碰到了。谢谢你,里希。以后我会警惕这一点。”
GO TO FULL VERSION