Java,参数中有3个点
以下方法中的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的评论。
这是通过可变参数 (可变数字参数)的Java方法。
如果你熟悉C语言,这与使用printf
函数的语法类似:
int printf(const char * format, ...);
但以一种types安全的方式:每个参数都必须符合指定的types(在您的示例中,它们应该都是String
)。
这是一个如何使用可变参数的简单示例:
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[]
作为参数。
可以说,这是一个语法糖的例子,因为它实际上是作为一个数组实现的(这并不意味着它是无用的) – 我更喜欢传递一个数组来保持清晰,并且还用给定types的数组声明方法。 而是一个意见,而不是一个答案,但。
可变长参数的可变参数是一个允许方法接受可变数量的参数(零个或多个)的特性。 使用可变参数很容易创build需要variables数量的参数的方法。 Java 5中增加了可变参数的特性。
可变参数的语法
在数据types之后,可变参数由三个省略号(三个点)分隔,其一般forms为
return_type method_name(data_type ... variableName){ }
需要可变参数
在Java 5之前,如果需要可变数量的参数,有两种方法来处理它
如果参数的最大数量,一个方法可以采取的是小的和已知的,那么可以创build方法的重载版本。 如果一个方法可以采用的最大参数数目很大或/和未知,那么方法是将这些参数放在一个数组中,并将它们传递给一个将数组作为参数的方法。 这两种方法很容易出错 – 每次构build一个参数数组并且难以维护 – 因为增加新的参数可能导致编写新的重载方法。
可变参数的优点
提供了一个更简单的选项。 由于不需要编写重载方法,所以代码更less。
可变参数的例子
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参数必须是方法声明的最后一个参数。
void displayValues(int a, int b, int … values) // OK void displayValues(int a, int b, int … values, int c) // compiler error
可变参数的另一个限制是只能有一个可变参数。
void displayValues(int a, int b, int … values, int … moreValues) // Compiler error
重载可变参数方法
可以重载一个采用可变参数的方法。 Varargs方法可以被重载 –
其可变参数的types可以不同。 通过添加其他参数。 重载可变参数方法的例子
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
可变参数和超载模糊
在某些情况下,调用可能不明确,而我们已经重载了可变参数方法。 我们来看一个例子
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)
同样的方法,如果我们有重载的方法,其中一个有一个types的vararg
参数方法,另一个方法有一个参数和相同types的vararg
参数,那么我们也有歧义 – 作为Exp – displayData(int ... values)
和displayData(int a, int ... values)
这两个重载的方法总是含糊不清。
另外为了说明一下,知道var-arg参数限制为1是很重要的,你不能有几个var-art参数。 例如,这是illigal:
public void myMethod(String... strings, int ... ints){ // method body }
只要把它想成C#中的关键字params
,如果你是从那个背景来的:)
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); } } }
一个真正常见的方式来看到一个清楚的例子,使用三个点,它是在Android的AsyncTask (今天是不是因为太多的RXJAVA,更不用说Google架构组件)使用最有名的方法之一,你可以find成千上万的例子来寻找这个词,理解和再也不会忘记这三个点的意义的最好方法就是他们expression一个……疑问……就像在通用语言中一样。 即不清楚必须通过的参数的数量,可能是0,可能是1可能更多(一个数组)… … –