可变参数和数组的区别

问题描述 投票:0回答:2

假设我有这样的代码

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
不能接受简单的
String
输入,而 vararg 可以接受变量
String
输入以及数组?

java arrays variadic-functions javap
2个回答
7
投票

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

是的,除了类文件中有额外的元数据来指示

method2
的参数是可变参数参数。这实际上只是参数上的额外数据 - 仅此而已。

您可以使用

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...);

2
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.