方法重载 - 对象与对象可变参数
Method oveloading - Object vs Object vararg
查看下面的代码:
// 1st method
private static void method(Object o){
System.out.println("object method");
}
// 2nd method
private static void method(Object... o){
System.out.println("object vararg method");
}
public static void main(String [] ar){
method(null); // 1st call
Integer value=null;
method(value); // 2nd call
}
我预计 1st call
和 2nd call
都应该调用 1st method
,认为 null
比 Object...
更愿意匹配 Object
可变参数。但我错了。
1st call
调用了 2nd method
2nd call
调用了 1st method
我的问题是 null
为什么或如何匹配我的代码中的 Object...
vararg 而不是 Object
?
因为 Object...
本质上是 Object[]
,并且由于 null
是有效的 Object[]
,它将匹配最具体的一个。
如果你有 3 个方法,第一个有 Object
参数,第二个有 SubClass
参数,最后一个有 SubSubClass
参数,最后一个将被选择。
而如果您将带有 String
参数的方法添加到您的原始代码中,则会出现编译时错误,因为不再有 null
的最具体匹配项。
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.
This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.
查看下面的代码:
// 1st method
private static void method(Object o){
System.out.println("object method");
}
// 2nd method
private static void method(Object... o){
System.out.println("object vararg method");
}
public static void main(String [] ar){
method(null); // 1st call
Integer value=null;
method(value); // 2nd call
}
我预计 1st call
和 2nd call
都应该调用 1st method
,认为 null
比 Object...
更愿意匹配 Object
可变参数。但我错了。
1st call
调用了2nd method
2nd call
调用了1st method
我的问题是 null
为什么或如何匹配我的代码中的 Object...
vararg 而不是 Object
?
因为 Object...
本质上是 Object[]
,并且由于 null
是有效的 Object[]
,它将匹配最具体的一个。
如果你有 3 个方法,第一个有 Object
参数,第二个有 SubClass
参数,最后一个有 SubSubClass
参数,最后一个将被选择。
而如果您将带有 String
参数的方法添加到您的原始代码中,则会出现编译时错误,因为不再有 null
的最具体匹配项。
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.
This guarantees that any calls that were valid in the Java programming language before Java SE 5.0 are not considered ambiguous as the result of the introduction of variable arity methods, implicit boxing and/or unboxing. However, the declaration of a variable arity method (§8.4.1) can change the method chosen for a given method method invocation expression, because a variable arity method is treated as a fixed arity method in the first phase. For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.