下面程序段能正常编译吗?为什么?
class Demo {
void func(String arg) {}
void func(String... args) {}
void func(String[] vars) {}
}
上面的类无法编译,会提示方法重复冲突。
因为 java 方法的变长参数只是一种语法糖,其本质上还是将变长的实际参数 args 包装成了一个数组,所以 String[] args 与 String... vars 会被当作是相同签名的方法,故在源码级别是不能同时存在的,所以无法编译通过。
下面的程序段执行结果是什么?
static void func(Object... varargs) {
System.out.println(varargs.length);
}
public static void main(String[] args) {
// F1
func(1024, new String[]{"1", "2", "3"});
// F2
func(new String[]{"1", "2", "3"});
// F3
func(1024, new Integer[]{1, 2, 3});
// F4
func(1, 2, 3);
// F5
func(new Integer[]{1, 2, 3});
// F6
func(new int[]{1, 2, 3});
// F7
func(1024, new int[]{1, 2, 3});
// F8
func(null, new int[]{1, 2, 3});
// F9
func(new Object[]{new String[]{"1","2","3"}});
// F10
func((Object) (new String[]{"1", "2", "3"}));
}
F1在编译时由于明确传入了两个实参,两个实参都是 Object 类型,所以能被正常识别长度是 2。
F2在编译时由于只传递了一个 String 数组,而 String 是对象类型的,所以在传递时被拆分成了数组长度个参数,所以长度是 3。
F3在编译时原理完全同 F1。
F4是最常见的正常调用了,没啥解释的。
F5在编译时原理完全同F2。
F6在编译时由于 int[] 没有办法直接转型成 Object[] ,因为基本类型与 Object 是无法匹配的,所以 int[] 被当作一个单纯的数组对象包装成类似 Object[]{int[]} 形式,所以长度是 1。而 Integer[] 本身就是 Object[],所以才有了 F2、F5 的现象。
F7、F8 在编译时同理 F1、F3。
F9 在编译时实质就是 Object[] 数组的一个元素,只不过这个元素又是一个 String[] 数组而已,所以打印为 1。
F10 在编译时虽然是 String[] 数组,但是在传递给变长参数时被强转成了 Object 类型,所以整个 String[] 数组被当成了一个整体,所以打印长度为 1。