Java,参数中有3个点


Answers:


985

这意味着可以将零个或多个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在他的评论中的澄清。


112
您可能会误以为“一个或多个”可以使用varargs来指定0或更大,并且它必须始终是方法中的最后一个参数。方法x(String ... params)可以称为x()或方法y(String pram,String ... params)可以称为y(“ 1”)
DamianLeszczyński-Vash 2010年

2
我希望这是否也行得通。myMethod(“一个”,“两个”,“三个”,新的String [] {“ a”,“ b”,“ c”“}))
2sb 2013年

2
为什么允许给方法0提供参数?这很可能导致ArrayIndexOutOfBoundsException。现在,您始终必须考虑到这种情况。
OlleSöderström13年

11
因为它们是可选的。由决定使用可选参数来正确实现该方法以处理零个或多个参数的开发人员决定。
奇斯瓦

@OlleSöderström另一个原因是在编译时将形式参数转换为数组。这意味着传入数组会产生相同的结果。由于在编译时不知道数组的长度,因此可以通过简单地调用来绕过至少传递一个元素的限制someMethod(new SomeType[] { })。那将是hack,不是吗?
MC Emperor

124

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

myMethod("foo", "bar");
myMethod("foo", "bar", "baz");
myMethod(new String[]{"foo", "var", "baz"}); // you can even pass 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]
    }
}

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


13
当代码到达字节码时,它一个数组。编译器仅支持其他所有语法。
Donal Fellows 2010年

如果我正确阅读了这些编辑内容,那么这个答案将大量借鉴kiswa和Lorenzo的观点。
马特·米切尔

3
@Graph比编辑它的答案更好,使它更正确,使其更正确。如果另一个答案是您改进的源泉,那就去吧。至少他对此很诚实(我认为他赞成其他有助于他的答案……对吗?)。

1
@我会指出我的诚实之后,他会诚实吗?感谢您的光临。
马特·米切尔

23

这是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同一类型的参数,那么我们也有模糊性-由于经验- displayData(int ... values)displayData(int a, int ... values)

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


15

这是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[]作为参数。


11

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


5

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

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


2

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


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

1
如果String...与相同String[],您能不能说那句话?
Scott Hunter

8
从技术上讲,这是不正确的,因为String[]需要一个参数(至少一个空数组),而String...不是(请参见上面的答案)。
Aurel

0

除了其他写得很好的答案以外,varagrs我发现一个有用的优点是,当我使用数组作为参数类型调用方法时,它消除了创建数组的麻烦;添加元素,然后发送它。取而代之的是,我可以使用所需的任意多个值来调用该方法。从零到很多。


0
  • 表示零个或多个相同数据类型的参数。
  • 它必须是构造函数或函数的最后一个参数。
  • 在相应的构造函数或函数中,只能有一个此类型参数。

范例1:

public class quest1 {

    public quest1(String... mynum) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1();

        quest1 q1=new quest1("hello");

    }
}

范例2:

public class quest1 {

    public quest1(int... at) {
        System.out.println("yee haa");
    }

    public quest1(String... at) {
        System.out.println("yee haa");
    }

    public static void main(String[] args) {
        quest1 q=new quest1("value");

        quest1 q1=new quest1(1);

    }

    public void name(String ... s) {

    }
}

输出:

怡哈

怡哈


-1

语法: (Triple dot ...)->意味着我们可以添加零个或多个对象以传递参数或类型数组。

public static void main(String[] args){}
public static void main(String... args){}

定义: 1)Object ...参数只是对Objects数组的引用。

2)('String []'或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(...)参数。即

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.   
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.