Tin*_*iny 21 java overloading variadic-functions java-6
以下代码无法编译.
package varargspkg;
public class Main {
public static void test(int... i) {
for (int t = 0; t < i.length; t++) {
System.out.println(i[t]);
}
System.out.println("int");
}
public static void test(float... f) {
for (int t = 0; t < f.length; t++) {
System.out.println(f[t]);
}
System.out.println("float");
}
public static void main(String[] args) {
test(1, 2); //Compilation error here quoted as follows.
}
}
Run Code Online (Sandbox Code Playgroud)
发出编译时错误.
对于测试的引用是不明确的,varargspkg.Main中的方法test(int ...)和varargspkg中的方法test(float ...)匹配
这似乎是显而易见的,因为在方法调用的参数值test(1, 2);可以提升int以及float
如果任何一个或两个参数后缀为F或f,则编译.
但是,如果我们使用相应的包装器类型表示方法签名中的接收参数,如下所示
public static void test(Integer... i) {
System.out.println("Integer" + Arrays.asList(i));
}
public static void test(Float... f) {
System.out.println("Float" + Arrays.asList(f));
}
Run Code Online (Sandbox Code Playgroud)
那么对方法的调用test(1, 2);不会发出任何编译错误.在这种情况下要调用的方法是接受一个Integervarargs参数的方法(前面代码片段中的第一个).
为什么在这种情况下错误与第一种情况没有报告?这里似乎都应用了自动装箱和自动类型提升.是否首先应用自动装箱以便解决错误?
Oracle文档说,
一般来说,你不应该重载varargs方法,否则程序员很难弄清楚调用哪些重载.
这个链接的最后一句话.然而,这是为了更好地理解varargs.
另外添加下面的代码编译就好了.
public class OverLoading {
public static void main(String[] args) {
load(1);
}
public static void load(int i) {
System.out.println("int");
}
public static void load(float i) {
System.out.println("float");
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
以下是指示编译错误的快照.我创建了一个新的应用程序,因此包名称不同.
我正在使用JDK 6.
Roh*_*ain 10
您可以Widen或Box,但你不能两者都做,除非你是boxing and widening到Object(一个int,整数(拳击),然后整数到对象(扩大)是合法的,因为每个类的子类Object,所以有可能Integer被传递到Object参数)
类似地,intto Number也是合法的(int - > Integer - > Number)因为Number是超类,Integer所以它是可能的.
我们在你的例子中看到这个: -
public static void test(Integer...i)
public static void test(Float...f)
Run Code Online (Sandbox Code Playgroud)
选择要选择的重载方法,组合Boxing,Widening和Var-args时,遵循一些规则: -
smallest可能的方法参数int可以成为Object通过Integer)int不能成为Long)因此,根据上述规则: -
当您将两个整数传递给上述函数时,
Widened然后
Boxed适合a Long,根据规则5是非法的(你不能加宽然后盒子).Integervar-args中.但在第一种情况下,你有var-args原始类型的方法: -
public static void test(int...i)
public static void test(float...f)
Run Code Online (Sandbox Code Playgroud)
然后test(1, 2)可以调用这两个方法(因为它们都不适合rule 1应用): -
var-args现在,当你有一个只有一个int和一个flost的方法时: -
public static void test(int i)
public static void test(float f)
Run Code Online (Sandbox Code Playgroud)
然后在调用时test(1),遵循规则1,并且选择最小可能的加宽(即int,根本不需要加宽的地方).因此将调用第一个方法.
有关更多信息,请参阅 JLS - Method Invocation Conversion