以下方法中 String
后面的 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
变量用作数组:
public void myMethod(String... strings){
for(String whatever : strings){
// do what ever you want
}
// the code above is equivalent to
for( int i = 0; i < strings.length; i++){
// classical for. In this case you use strings[i]
}
}
这个答案大量借鉴了 kiswa 和 Lorenzo 的……以及 Graphain 的评论。
这是可变参数 :)
可变长度参数的 varargs 缩写是允许方法接受可变数量的参数(零个或多个)的功能。使用可变参数,创建需要可变数量参数的方法变得很简单。 Java 5 中增加了变量参数的特性。
可变参数的语法
可变参数由数据类型后面的三个省略号(三个点)分隔,其一般形式为
return_type method_name(data_type ... variableName){
}
需要可变参数
在 Java 5 之前,如果需要可变数量的参数,有两种方法来处理它
如果方法可以采用的最大参数数量很小且已知,则可以创建该方法的重载版本。如果一个方法可以采用的最大参数数量很大或/并且未知,那么方法是将这些参数放在一个数组中,并将它们传递给一个将数组作为参数的方法。这两种方法很容易出错 - 每次都构造参数数组并且难以维护 - 因为添加新参数可能会导致编写新的重载方法。
可变参数的优点
提供了一个更简单的选择。更少的代码,因为不需要编写重载方法。
可变参数示例
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
从程序中可以看出,这里使用length来查找传递给方法的参数个数。这是可能的,因为可变参数是作为数组隐式传递的。作为可变参数传递的任何参数都存储在一个数组中,该数组由赋予可变参数的名称引用。在这个程序中,数组名称是值。另请注意,使用不同数量的参数调用方法,首先使用四个参数调用,然后是三个参数,然后是零参数。所有这些调用都由采用可变参数的相同方法处理。
可变参数的限制
方法中可以有其他带有可变参数的参数,但是在这种情况下,可变参数必须是方法声明的最后一个参数。
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 方法可以通过 -
其 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 方法时,调用可能会模棱两可。让我们看一个例子
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
参数,那么我们也会有歧义 - As Exp - displayData(int ... values)
和 {4 }
这两个重载的方法总是会产生歧义。
这是传递 varargs(可变数字参数)的 Java 方式。
如果您熟悉 C,这类似于使用 printf
函数的 ...
语法:
int printf(const char * format, ...);
但以类型安全的方式:每个参数都必须符合指定的类型(在您的示例中,它们都应该是 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[]
作为参数。
可以说,它是语法糖的一个例子,因为它无论如何都是作为一个数组实现的(这并不意味着它没有用) - 我更喜欢传递一个数组以保持清晰,并且还声明具有给定类型数组的方法。不过,与其说是答案,不如说是意见。
另外为了阐明一些观点,重要的是要知道 var-arg 参数仅限于一个,并且您不能拥有多个 var-art 参数。例如这是非法的:
public void myMethod(String... strings, int ... ints){
// method body
}
如果您来自该背景,只需将其视为 C# 中的关键字 params
:)
一种非常常见的方式来查看使用三个点的清晰示例,它出现在 android AsyncTask 中最着名的方法之一中(由于 RXJAVA,今天没有太多使用,更不用说 Google 架构组件了),您可以找到数千个搜索该术语的示例,而最好的理解和永远不会忘记三个点的含义的方法是它们表达了......怀疑......就像在通用语言中一样。即不清楚必须传递的参数数量,可能是 0,可能是 1,可能是更多(一个数组)......
除了其他写得很好的答案之外,我发现 varagrs
的一个优点是有用的是,当我以数组作为参数类型调用方法时,它消除了创建数组的痛苦;添加元素,然后发送。相反,我可以使用任意数量的值调用该方法;从零到很多。
语法:(三点...) --> 表示我们可以添加零个或多个对象,传入一个参数或传递一个对象类型的数组。
public static void main(String[] args){}
public static void main(String... args){}
定义: 1) Object ... 参数只是对对象数组的引用。
2) ('String []' or String ... ) 它可以处理任意数量的字符串对象。在内部,它使用引用类型对象的数组。
i.e. Suppose we pass an Object array to the ... argument - will the resultant argument value be a two-dimensional array - because an Object[] is itself an Object:
3)如果你想用一个参数调用方法并且它恰好是一个数组,你必须显式地将它包装在
another. method(new Object[]{array});
OR
method((Object)array), which will auto-wrap.
应用:主要在参数数量是动态的(在运行时知道的参数数量)和覆盖时使用。一般规则 - 在方法中,我们可以传递任何类型和任意数量的参数。我们不能在任何特定参数之前添加 object(...) 参数。 IE
void m1(String ..., String s) this is a wrong approach give syntax error.
void m1(String s, String ...); This is a right approach. Must always give last order prefernces.
不定期副业成功案例分享
someMethod(new SomeType[] { })
来绕过传递至少一个元素的限制。那将是一个黑客,不是吗?