Java,参数中的 3 个点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3158730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:56:28  来源:igfitidea点击:

Java, 3 dots in parameters

javavariadic-functions

提问by Vikram

What do the 3 dots in the following method mean?

以下方法中的 3 个点是什么意思?

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

采纳答案by kiswa

It means that zero or more String objects (or an array of them) may be passed as the argument(s) for that method.

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

See the "Arbitrary Number of Arguments" section here: http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html#varargs

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

In your example, you could call it as any of the following:

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

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

Important Note:The argument(s) passed in this way is always an array - even if there's just one. Make sure you treat it that way in the method body.

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

Important Note 2:The argument that gets the ...must be the last in the method signature. So, myMethod(int i, String... strings)is okay, but myMethod(String... strings, int i)is not okay.

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

Thanks to Vash for the clarifications in his comment.

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

回答by Cristian

That feature is called varargs, and it's a feature introduced in Java 5. It means that function can receive multiple Stringarguments:

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

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

Then, you can use the Stringvar as an array:

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

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]
    }
}

This answer borrows heavily from kiswa's and Lorenzo's... and also from the Graphain's comment.

这个答案大量借鉴了 kiswa 和 Lorenzo 的……以及 Graphain 的评论。

回答by lornova

This is the Java way to pass varargs(variable number arguments).

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

If you are familiar with C, this is similar to the ...syntax used it the printffunction:

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

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

but in a type safe fashion: every argument has to comply with the specified type (in your sample, they should be all String).

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

This is a simple sample of how you can use varargs:

这是一个关于如何使用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");
   }
}

The ...argument is actually an array, so you could pass a String[]as the parameter.

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

回答by MichaelS

Arguably, it is an example of syntactic sugar, since it is implemented as an array anyways (which doesn't mean it's useless) - I prefer passing an array to keep it clear, and also declare methods with arrays of given type. Rather an opinion than an answer, though.

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

回答by Ε Г И ? И О

Just think of it as the keyword paramsin C#, if you are coming from that background :)

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

回答by trocchietto

A really common way to see a clear example of the use of the three dots it is present in one of the most famous methods in android AsyncTask( that today is not used too much because of RXJAVA, not to mention the Google Architecture components), you can find thousands of examples searching for this term, and the best way to understand and never forget anymore the meaning of the three dots is that they express a ...doubt... just like in the common language. Namely it is not clear the number of parameters that have to be passed, could be 0, could be 1 could be more( an array)...

一个非常常见的方式来查看三个点的使用的清晰示例,它出现在 android AsyncTask 中最著名的方法之一中(由于 RXJAVA,今天没有使用太多,更不用说 Google 架构组件了),你可以找到数以千计的搜索这个词的例子,理解和永远不会忘记这三个点的含义的最好方法是它们表达了一个......怀疑......就像在通用语言中一样。即不清楚必须传递的参数数量,可以是0,可以是1,可以是更多(数组)......

回答by Mr.Q

Also to shed some light, it is important to know that var-arg parameters are limited to one and you can't have several var-art params. For example this is illigal:

同样要说明一点,重要的是要知道 var-arg 参数仅限于一个,并且不能有多个 var-art 参数。例如这是非法的:

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

回答by SIW

It's Varargs:)

它是可变参数:)

The varargs short for variable-length arguments is a feature that allows the method to accept variable number of arguments (zero or more). With varargs it has become simple to create methods that need to take a variable number of arguments. The feature of variable argument has been added in Java 5.

varargs 是可变长度参数的缩写,它允许方法接受可变数量的参数(零个或多个)。使用可变参数,创建需要可变数量参数的方法变得很简单。Java 5 中增加了可变参数的特性。

Syntax of varargs

可变参数的语法

A vararg is secified by three ellipsis (three dots) after the data type, its general form is

vararg 由数据类型后的三个省略号(三个点)表示,其一般形式为

return_type method_name(data_type ... variableName){
}  

Need for varargs

需要可变参数

Prior to Java 5, in case there was a need of variable number of arguments, there were two ways to handle it

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

If the max number of arguments, a method can take was small and known, then overloaded versions of the method could be created. If the maximum number of arguments a method could take was large or/and unknown then the approach was to put those arguments in an array and pass them to a method which takes array as a parameter. These 2 approaches were error-prone - constructing an array of parameters every time and difficult to maintain - as the addition of new argument may result in writing a new overloaded method.

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

Advantages of varargs

可变参数的优点

Offers a much simpler option. Less code as no need to write overloaded methods.

提供了一个更简单的选择。更少的代码,因为不需要编写重载的方法。

Example of 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

It can be seen from the program that length is used here to find the number of arguments passed to the method. It is possible because varargs are implicitly passed as an array. Whatever arguments are passed as varargs are stored in an array which is referred by the name given to varargs. In this program array name is values. Also note that method is called with different number of argument, first call with four arguments, then three arguments and then with zero arguments. All these calls are handled by the same method which takes varargs.

从程序中可以看出,这里使用length来求传递给方法的参数个数。这是可能的,因为可变参数是作为数组隐式传递的。作为可变参数传递的任何参数都存储在一个数组中,该数组由赋予可变参数的名称引用。在这个程序中,数组名称是值。还要注意,方法是用不同数量的参数调用的,首先用四个参数调用,然后用三个参数调用,然后用零个参数调用。所有这些调用都由采用可变参数的相同方法处理。

Restriction with varargs

可变参数限制

It is possible to have other parameters with varargs parameter in a method, however in that case, varargs parameter must be the last parameter declared by the method.

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

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

Another restriction with varargs is that there must be only one varargs parameter.

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

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

Overloading varargs Methods

重载可变参数方法

It is possible to overload a method that takes varargs parameter. Varargs method can be overloaded by -

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

Types of its vararg parameter can be different. By adding other parameters. Example of overloading varargs method

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

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 and overloading ambiguity

可变参数和重载歧义

In some cases call may be ambiguous while we have overloaded varargs method. Let's see an example

在某些情况下,当我们重载 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();
 }
}

In this program when we make a call to displayData() method without any parameter it throws error, because compiler is not sure whether this method call is for displayData(String ... values)or displayData(int ... values)

在这个程序中,当我们在没有任何参数的情况下调用 displayData() 方法时它会抛出错误,因为编译器不确定这个方法调用是为了displayData(String ... values)还是displayData(int ... values)

Same way if we have overloaded methods where one has the varargmethod of one type and another method has one parameter and varargparameter of the same type, then also we have the ambiguity - As Exp - displayData(int ... values)and displayData(int a, int ... values)

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

These two overloaded methods will always have ambiguity.

这两个重载的方法总会有歧义。

回答by Uddhav Gautam

String...is the same as String[]

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

回答by PhantomReference

Adding to the other well-written answers, an advantage of varagrsI found useful is that, when I call a method with array as a parameter type, it takes away the pain of creating an array; add elements and then send it. Instead, I can just call the method with as many values as I want; from zero to many.

添加到其他写得很好的答案中,varagrs我发现有用的一个优点是,当我以数组作为参数类型调用方法时,它消除了创建数组的痛苦;添加元素然后发送。相反,我可以使用任意数量的值调用该方法;从零到很多。