不明确的重载方法调用已解决
Ambiguous Overloaded method call resolved
当我调用时,call('a');
它输出 "char" 这很好,因为 char 原始类型将优先于将其装箱为 Character。
static void call(char i){
System.out.println("char");
}
static void call(Character i){
System.out.println("Character");
}
对 call('a', 'a');
的调用为何不明确?
static void call(char i, Character j){
System.out.println("char");
}
static void call(Character i, Character j){
System.out.println("Character");
}
我在想的是,对于第二个参数,编译器必须进行装箱,对于第一个参数,完美匹配是 char 原始类型,因此对 call('a','a');
的调用可以解析为 call(char i, Character j)
方法。
显然我理解错了,请大神解释一下。
解释特定此类示例的一些链接会有所帮助。
How is call to call('a', 'a');
is ambiguous?
因为为了使 (char i, Character j)
重载适用,有关装箱的规则开始发挥作用 - 此时 both 调用都适用。这是确定方法签名的第二阶段 (JLS 15.12.2):
The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
因此在第 2 阶段,两种方法都适用,但确定最具体方法 (JLS 15.12.2.5) 的规则不会使任何一种调用比彼此更具体。这不是 "unboxed is more specific than boxed" 的问题 - 这是 "can I resolve this with boxing" 之前的 "can I resolve this without any boxing" 的问题。
答案在JLS 15.12.2 Compile-Time Step 2: Determine Method Signature:
对于使用 char
和 Character
的第一个 call
方法,编译器只需要第一阶段就可以知道要调用哪个方法。在第一阶段,它不会混合盒装类型和原始类型:
The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
但是,在您使用 2 个参数(char
和 Character
,以及 Character
和 Character
)的调用中,编译器需要到达 second阶段试图区分它们,并且在那个特定点上两种方法都有效:
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation.
当我调用时,call('a');
它输出 "char" 这很好,因为 char 原始类型将优先于将其装箱为 Character。
static void call(char i){
System.out.println("char");
}
static void call(Character i){
System.out.println("Character");
}
对 call('a', 'a');
的调用为何不明确?
static void call(char i, Character j){
System.out.println("char");
}
static void call(Character i, Character j){
System.out.println("Character");
}
我在想的是,对于第二个参数,编译器必须进行装箱,对于第一个参数,完美匹配是 char 原始类型,因此对 call('a','a');
的调用可以解析为 call(char i, Character j)
方法。
显然我理解错了,请大神解释一下。
解释特定此类示例的一些链接会有所帮助。
How is call to
call('a', 'a');
is ambiguous?
因为为了使 (char i, Character j)
重载适用,有关装箱的规则开始发挥作用 - 此时 both 调用都适用。这是确定方法签名的第二阶段 (JLS 15.12.2):
The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
因此在第 2 阶段,两种方法都适用,但确定最具体方法 (JLS 15.12.2.5) 的规则不会使任何一种调用比彼此更具体。这不是 "unboxed is more specific than boxed" 的问题 - 这是 "can I resolve this with boxing" 之前的 "can I resolve this without any boxing" 的问题。
答案在JLS 15.12.2 Compile-Time Step 2: Determine Method Signature:
对于使用 char
和 Character
的第一个 call
方法,编译器只需要第一阶段就可以知道要调用哪个方法。在第一阶段,它不会混合盒装类型和原始类型:
The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
但是,在您使用 2 个参数(char
和 Character
,以及 Character
和 Character
)的调用中,编译器需要到达 second阶段试图区分它们,并且在那个特定点上两种方法都有效:
The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation.