Java中方法重载中的Varargs
以下代码无法编译。
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.
}
}
发出编译时错误。
对test的引用是模棱两可的,varargspkg.Main中的方法test(int
…)和varargspkg.Main中的方法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));
}
那么对该方法的调用test(1,
2);不会发出任何编译错误。在这种情况下,要调用的方法是接受一个Integer
varargs参数(上一代码段中的第一个)的方法。
为什么在这种情况下没有报告第一种情况下的错误?似乎自动装箱和自动类型升级都在这里应用。是否先应用自动装箱才能解决错误?
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");
}
}
以下是指示编译错误的快照。我创建了一个新的应用程序,因此程序包名称不同。
我正在使用JDK 6。
回答:
You can either Widen
or Box
but you cannot do both, unless you are boxing
and widening to Object
(An int to Integer(Boxing) and then Integer to
Object(Widening) is legal, since every class is a subclass of Object
, so it
is possible for Integer
to be passed to Object
parameter)
Similarly an int
to Number
is also legal (int -> Integer -> Number) Since
Number is the super class of Integer
it is possible.
public static void test(Integer...i)public static void test(Float...f)
There are some rules that are followed when selecting which overloaded method
to select, when Boxing, Widening, and Var-args are combined: -
- Primitive widening uses the
smallest
method argument possible - Wrapper type cannot be widened to another Wrapper type
- You can Box from int to Integer and widen to Object but no to Long
- Widening beats Boxing, Boxing beats Var-args.
- You can Box and then Widen (An
int
can becomeObject
viaInteger
) - You cannot Widen and then Box (An
int
cannot becomeLong
) - You cannot combine var-args, with either widening or boxing
So, based on the above given rules: -
- according to rule 3, it will have to be first
Widened
and thenBoxed
to fit into aLong
, which is illegal according to rule 5 (You cannot Widen and then Box). - So, it is Boxed to store in
Integer
var-args.
回答:
public static void test(int...i)public static void test(float...f)
Then test(1, 2)
can invoke both the methods (Since neither of them is more
suitable for rule 1
to apply) : -
- In first case it will be
var-args
- In second case, it will be Widening and then Var-args (which is allowed)
Now, when you have methods with exactly one int and one flost: -
public static void test(int i)public static void test(float f)
Then on invoking using test(1)
, rule 1 is followed, and smallest possible
widening (i.e. the int
where no widening is needed at all) is chosen. So 1st
method will be invoked.
For more information, you can refer to JLS - Method Invocation
Conversion
以上是 Java中方法重载中的Varargs 的全部内容, 来源链接: utcz.com/qa/398749.html