我正在学习Java,遇到了一些关于重载的问题。以以下函数为例:
f('a', 'a');
If we have two definition as:
static void f(int i, char j){
System.out.println("int_char");
}
static void f(double i, char j){
System.out.println("double_char");
}
没问题。因为所有的第二个参数都完全匹配。但是第一个参数,它们都使用了 widen。对于 char 来说,widen 的顺序是:
char -> int -> long -> float -> double
将char转换成int只需要一步,但是将其转换为double需要四步。因此结果是:
int_char
但是,如果我更改参数的顺序如下:
static void f(int i, char j){
System.out.println("int_char");
}
static void f(char i, double j){
System.out.println("char_double");
}
编译器会提示模棱两可的错误。为什么?
另一种情况如下:
static void f(char i, Character j){
System.out.println("char_Character");
}
static void f(Character i, Character j){
System.out.println("Character_Character");
}
第二个参数都使用自动装箱。但是void f(char i, Character j)的第一个参数完全匹配。为什么这两个函数一起使用会导致歧义?
最后,如果这些函数中有任何一个出现在以下函数中:
static void f(Character... i){
System.out.println("Character_varargs");
}
输出结果不是Character_varargs,因为widen > boxing > varargs。但当两个模糊的函数与Character_varargs函数一起出现时,情况就变得复杂了:
static void f(char i, Character j){
System.out.println("char_Character");
}
static void f(Character i, Character j){
System.out.println("Character_Character");
}
static void f(Character... i){
System.out.println("Character_varargs");
}
结果将是Character_varargs。为什么?即使我们添加了一些非歧义和优先级更高的重载函数,例如:
static void f(int i, char j){
System.out.println("int_char");
}
static void f(char i, double j){
System.out.println("char_double");
}
static void f(int i, double j){
System.out.println("int_double");
}
static void f(Character... i){
System.out.println("Character_varargs");
}
结果仍然是Character_varargs。为什么?如果只考虑void f(int i, double j)和void f(Character… i),输出应该是int_double。
当编译器遇到有歧义的函数时,它是否直接“跳过”其他可能性,而选择可变参数函数(如果有)?
谢谢!