Java Varargs

Java 中的可变参数是什么?

假设您正在创建一个 Java 方法。但是,您不确定方法将接受多少个参数。为了解决这个问题,Java 1.5 引入了可变参数。

Varargs 是可变参数的简称。在 Java 中,方法的参数可以接受任意数量的值。这个可以接受可变数量值的参数称为可变参数。


实现可变参数的语法如下

accessModifier methodName(datatype… arg) {
    // method body
}

为了定义可变参数,在方法的正式参数中使用 ...(三个点)。

接受可变数量参数的方法称为可变参数方法,或简称为 varargs 方法。


首先,让我们看看不使用可变参数的示例

class NoVararg {

    public int sumNumber(int a, int b){
        return a+b;
    }

    public int sumNumber(int a, int b, int c){
        return a+b+c;
    }

    public static void main( String[] args ) {
        NoVararg obj = new NoVararg();
        System.out.println(obj.sumNumber(1, 2));
        System.out.println(obj.sumNumber(1, 2, 3));
    }
}

运行此程序时,输出将是

3
6

正如您清楚看到的,您必须重载 sumNumber() 方法才能使其处理 3 个参数。

如果用户想添加 5 个数字或 10 个或 100 个数字怎么办?

可以使用可变参数以一种巧妙的方式来处理。让我们看一个代码示例


示例:可变参数的工作原理

class VarargExample {

    public int sumNumber(int ... args){
        System.out.println("argument length: " + args.length);
        int sum = 0;
        for(int x: args){
            sum += x;
        }
        return sum;
    }

    public static void main( String[] args ) {
        VarargExample ex = new VarargExample();

        int sum2 = ex.sumNumber(2, 4);
        System.out.println("sum2 = " + sum2);

        int sum3 = ex.sumNumber(1, 3, 5);
        System.out.println("sum3 = " + sum3);

        int sum4 = ex.sumNumber(1, 3, 5, 7);
        System.out.println("sum4 = " + sum4);
    }
}

输出:

argument length: 2
sum2 = 6
argument length: 3
sum3 = 9
argument length: 4
sum4 = 16

在这里,sumNumber() 方法返回传递给它的 int 参数的总和(不考虑传递的参数数量)。


注意:正如您所看到的,在某些情况下,可变参数非常有用。但是,如果您确定传递给方法的参数数量,请改用方法重载。例如,如果您确定 sumNumber() 方法仅用于计算 2 个或 3 个参数的总和,请使用方法重载,如第一个示例所示。


让我们再举一个例子。Java 库中定义的 format() 方法接受可变参数。在 JDK 中,format() 方法定义如下

public static String format(Locale l, String format, Object... args) {
    // body
}

示例:format() 方法

class Company {
  public static void main(String[] args) {
    String siteName = "programiz.com";
    int empCount = 6;
    String type = "tutorial website";
    System.out.println(
        String.format(
          "Site Name : %s, Emp Count: %d Type: %s",
            siteName, empCount, type
          )
        );
  }
}

输出:

Site Name : programiz.com, Emp Count: 6 Type: tutorial website

可变参数在后台是如何工作的?

让我们考虑以下伪代码

public int sumNumber(int ... nums) {
    // method body
}

... 语法告诉 Java 编译器该方法可以使用零个或多个参数进行调用。因此,nums 变量被隐式声明为 int[ ] 类型的 数组。因此,在方法内部,nums 变量使用数组语法进行访问。

如果没有参数,nums 的长度为 0。


重载可变参数方法

与常规方法类似,您可以重载可变参数方法。例如,

在学习重载可变参数方法之前,请确保先学习 Java 方法重载

class VarargOverload {

    private void test(int ... args){
        int sum = 0;
        for (int i: args) {
            sum += i;
        }
        System.out.println("sum = " + sum);
    }

    private void test(boolean p, String ... args){
        boolean negate = !p;
        System.out.println("negate = " + negate);
        System.out.println("args.length = "+ args.length);
    }

    public static void main( String[] args ) {
        VarargOverload obj = new VarargOverload();
        obj.test(1, 2, 3);
        obj.test(true, "hello", "world");
    }
}

输出:

sum = 6
negate = false
args.length = 2

在上面的程序中,通过更改 test() 方法接受的参数数量来重载它。


使用可变参数时需要记住的事情

以下是使用 Java 可变参数时应记住的几点

1. 定义方法签名时,始终将可变参数放在最后。

可变参数必须是传递给方法的最后一个参数。例如,您像这样调用了 doSomething() 方法

doSomething(1, 2, 3, 4);

并且,您的 doSomething() 方法定义如下

// incorrect method declaration

public void doSomething(int ... nums, int p){
    // method body
}

在这种情况下,编译器无法确定传递给 nums 的参数数量。

但是,如果您将方法定义为

public void doSomething(int p, int ... nums) {
    // method body
}

Java 编译器会将第一个参数分配给 p,其余的 int 参数分配给 nums

2. 一个方法只能有一个可变参数参数。

例如,此方法声明不正确

int doSomething(int p, float ... floatNums, double ... doubleNums) {
    // code
}

可变参数方法重载中的歧义

让我们考虑您重载了 test() 方法,如下所示

class Demo { 
  
  static void test(int ... vargs) {
    // method body
  }
    
  static void test(int n, int ... vargs) {
    // method body
  }
}

在上面的程序中,当您尝试调用 test() 方法时,即使 test() 方法已重载并接受不同数量的参数,编译器也会感到困惑。

编译器不知道该调用哪个方法。编译器可能认为您正试图使用一个可变参数参数调用 test(int ... vargs)。此外,编译器可能认为您正试图将参数传递给第一个参数,并使第二个参数为空,从而调用 test(int n, int ... vargs)

由于存在两种可能性,因此会导致歧义。因此,有时您可能需要使用两个不同的方法名,而不是重载可变参数方法。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战