Java,参数中有 3 个点

public void myMethod(String... strings){
    // method body
}

答案

这意味着可以将零个或多个 String 对象(或它们的数组)作为该方法的参数传递。

请参见此处的 “任意数量的参数” 部分: http : //java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

在您的示例中,可以将其称为以下任意一种:

myMethod(); // Likely useless, but possible
myMethod("one", "two", "three");
myMethod("solo");
myMethod(new String[]{"a", "b", "c"});

重要说明:以这种方式传递的参数始终是一个数组 - 即使只有一个。确保在方法主体中以这种方式对待它。

重要说明 2:获取...的参数必须是方法签名中的最后一个。因此, myMethod(int i, String... strings)可以,但是myMethod(String... strings, int i)则不能。

感谢 Vash 在他的评论中的澄清。

该功能称为varargs ,它是 Java 5 中引入的功能。这意味着该函数可以接收多个String参数:

myMethod("foo", "bar");
myMethod("foo", "bar", "baz");
myMethod(new String[]{"foo", "var", "baz"}); // you can even pass an array

然后,您可以将String var 用作数组:

public void myMethod(String... strings){
    for(String whatever : strings){
        // do what ever you want
    }

    // the code above is is equivalent to
    for( int i = 0; i < strings.length; i++){
        // classical for. In this case you use strings[i]
    }
}

这个答案在很大程度上借鉴了 kiswa 和 Lorenzo 的观点…… 以及 Graphain 的评论。

这是 Varargs :)

可变长度参数的 varargs 缩写是一项功能,它允许方法接受可变数量的参数(零个或多个)。使用 varargs,创建需要采用可变数量参数的方法变得很简单。变量自变量的功能已在 Java 5 中添加。

varargs 的语法

数据类型后,可变参数由三个省略号(三个点)保护,其一般形式为

return_type method_name(data_type ... variableName){
}

需要可变参数

在 Java 5 之前,如果需要可变数量的参数,则有两种方法来处理它

如果一个方法可以容纳的最大参数个数很小且已知,则可以创建该方法的重载版本。如果一个方法可以容纳的最大参数数量很大或未知,那么该方法就是将这些参数放入数组中并将其传递给以数组为参数的方法。这两种方法容易出错 - 每次都构造一个参数数组并且很难维护 - 因为添加新参数可能会导致编写新的重载方法。

varargs 的优点

提供更简单的选择。更少的代码,因为无需编写重载方法。

可变参数的示例

public class VarargsExample {
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 public static void main(String[] args) {
  VarargsExample vObj = new VarargsExample();
  // four args
  vObj.displayData("var", "args", "are", "passed");
  //three args
  vObj.displayData("Three", "args", "passed");
  // no-arg
  vObj.displayData();
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 
Number of arguments passed 3
Three 
args 
passed 
Number of arguments passed 0

从程序可以看出,这里使用长度来查找传递给方法的参数数量。可能是因为 varargs 作为数组隐式传递。无论将什么参数作为 varargs 传递到存储在数组中,该数组均由赋予 varargs 的名称引用。在此程序中,数组名称是值。还要注意,使用不同数量的参数调用方法,首先使用四个参数,然后使用三个参数,然后使用零参数来调用。所有这些调用均由采用 varargs 的相同方法处理。

varargs 的限制

一个方法中可能有其他带有 varargs 参数的参数,但是在那种情况下,varargs 参数必须是该方法声明的最后一个参数。

void displayValues(int a, int b, int … values) // OK
   void displayValues(int a, int b, int … values, int c) // compiler error

varargs 的另一个限制是只能有一个 varargs 参数。

void displayValues(int a, int b, int … values, int … moreValues) // Compiler error

重载 varargs 方法

可以重载采用 varargs 参数的方法。 Varargs 方法可以通过 - 重载

其 vararg 参数的类型可以不同。通过添加其他参数。重载 varargs 方法的示例

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 // Method with int vararg and one more string parameter
 public void displayData(String a, int ... values){
  System.out.println(" a " + a);
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // One String param and two int args
  vObj.displayData("Test", 20, 30);
 }
}
Output

Number of arguments passed 4
var 
args 
are 
passed 

Number of arguments passed 2
10 
20

 a Test
Number of arguments passed 2
20 
30

Varargs 和过载歧义

在某些情况下,当我们重载 varargs 方法时,调用可能不明确。让我们看一个例子

public class OverloadingVarargsExp {
 // Method which has string vararg parameter
 public void displayData(String ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(String s : values){
   System.out.println(s + " ");
  }
 }

 // Method which has int vararg parameter
 public void displayData(int ... values){
  System.out.println("Number of arguments passed " + values.length);
  for(int i : values){
   System.out.println(i + " ");
  }
 }

 public static void main(String[] args) {
  OverloadingVarargsExp vObj = new OverloadingVarargsExp();
  // four string args
  vObj.displayData("var", "args", "are", "passed");

  // two int args
  vObj.displayData(10, 20);

  // This call is ambiguous
  vObj.displayData();
 }
}

在此程序中,当我们不带任何参数调用 displayData()方法时,会引发错误,因为编译器不确定此方法调用是针对displayData(String ... values)还是displayData(int ... values)

如果我们有一个方法具有一种类型的vararg方法而另一种方法具有一个相同类型的参数和vararg参数的重载方法,则我们也具有歧义 - 如 Exp- displayData(int ... values)displayData(int a, int ... values)

这两个重载方法将始终存在歧义。

这是 Java 传递varargs (可变数字参数)的方法。

如果您熟悉 C,则类似于printf函数使用的...语法:

int printf(const char * format, ...);

但是以一种类型安全的方式:每个参数都必须符合指定的类型(在您的示例中,它们都应为String )。

这是有关如何使用varargs的简单示例:

class VarargSample {

   public static void PrintMultipleStrings(String... strings) {
      for( String s : strings ) {
          System.out.println(s);
      }
   }

   public static void main(String[] args) {
      PrintMultipleStrings("Hello", "world");
   }
}

...参数实际上是一个数组,因此您可以传递String[]作为参数。

可以说,这是语法糖的一个例子,因为无论如何它都是作为数组实现的(这并不意味着它没有用)- 我更喜欢传递数组以使其清晰,并声明具有给定类型数组的方法。不过,与其说是答案,不如说是一种意见。

如果您来自该背景,只需将其视为 C#中的关键字params :)

同样,为了阐明一些信息,知道 var-arg 参数限制为一个,并且不能有多个 var-art 参数也是很重要的。例如,这是非法的:

public void myMethod(String... strings, int ... ints){
// method body
}

这是查看三个点用法的清晰示例的一种非常常见的方式,它存在于 android AsyncTask 中最著名的方法之一中(由于 RXJAVA,今天使用不多,更不用说 Google Architecture 组件了),您可以找到成千上万个搜索该词的示例,理解和永远不会忘记这三个点的最佳方法是,它们就像普通语言一样表达了 “怀疑”。即尚不清楚必须传递的参数数量,可以是 0,可以是 1 可以更多(一个数组)...

String...String[]相同

import java.lang.*;

        public class MyClassTest {

        //public static void main(String... args) { 

        public static void main(String[] args) {
        for(String str: args) {
        System.out.println(str);

        }
        }
        }