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);可以提升intfloat

如果任何一个或两个参数都带有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);不会发出任何编译错误。在这种情况下,要调用的方法是接受一个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");

}

}


以下是指示编译错误的快照。我创建了一个新的应用程序,因此程序包名称不同。

enter image description</p><p>here

我正在使用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: -

  1. Primitive widening uses the smallest method argument possible
  2. Wrapper type cannot be widened to another Wrapper type
  3. You can Box from int to Integer and widen to Object but no to Long
  4. Widening beats Boxing, Boxing beats Var-args.
  5. You can Box and then Widen (An int can become Object via Integer)
  6. You cannot Widen and then Box (An int cannot become Long)
  7. 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 then Boxed to fit into a Long, 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

回到顶部