3

假设我有一个类似的代码

public class HelloWorld {

    public static String method1(String[] array){return ""+array.length;}
    public static String method2(String... array){return ""+array.length;}


    public static void main(String args[]) {
        System.out.println(method1(new String[]{"test"})); //allowed
        //System.out.println(method1("test")); Not allowed
        System.out.println(method2(new String[]{"test"}));  //allowed
        System.out.println(method2("test")); //allowed
    }
}

当我做javap HelloWorld

C:\Users\athakur\JavaProjectWorkspace\HelloWorld\bin\test>javap HelloWorld
Compiled from "HelloWorld.java"
public class test.HelloWorld extends java.lang.Object{
    public test.HelloWorld();
    public static java.lang.String method1(java.lang.String[]);
    public static java.lang.String method2(java.lang.String[]);
    public static void main(java.lang.String[]);
}

因此,根据类文件 method1 和 method2 采用相同的数组参数。那么为什么他们可以接受的输入不同呢?

像 method1 不能接受简单的字符串输入,而 var arg 可以接受变量字符串输入以及数组?

4

2 回答 2

7

因此,根据类文件 method1 和 method2 采用相同的数组参数。

是的,除了类文件中有额外的元数据表明参数 formethod2是可变参数。这实际上只是参数上的额外数据——仅此而已。

您可以使用反射检测它Parameter.isVarArgs

这意味着编译器愿意接受这样的调用:

method2("test")

并将其隐式转换为

method2(new String[] { "test" })

您并不总是想要这种行为,因此必须使用 varargs 语法在参数上明确指定它。

我怀疑您还使用了稍微旧的版本javap,如果它没有向您显示两个方法声明之间的区别。在我的版本(Java 8)上,我得到:

public static java.lang.String method1(java.lang.String[]);
public static java.lang.String method2(java.lang.String...);
于 2014-06-08T14:35:11.643 回答
2

唯一的区别是方法的签名可能具有可变数量的参数,而不是数组参数,您只能传递一个参数。无论如何,将数组作为可变参数传递给方法被接受并将在内部使用。另一方面,可变参数将被转换为数组并在那里使用。

当您将数组作为参数传递给这两种方法时。要回答您的问题,请不要使用数组

System.out.println(method2("test")); //allowed
System.out.println(method2("test","test2")); //allowed

正如您所注意到的,这仅在您使用 vararg 参数时才有效。

于 2014-06-08T14:44:13.650 回答