Java、パラメーターに3つのドット


回答:


987

つまり、そのメソッドの引数として0個以上の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"});

重要な注意:この方法で渡される引数は、配列が1つしかない場合でも、常に配列です。メソッド本体でそのように扱うことを確認してください。

重要な注意2:を取得する引数...は、メソッドシグネチャの最後でなければなりません。だから、myMethod(int i, String... strings)大丈夫ですが、大丈夫でmyMethod(String... strings, int i)はありません。

コメントを明確にしてくれたVashに感謝します。


112
あなたは間違っています、その「1つ以上」では、varargsで0以上を指定でき、これは常にメソッドの最後のパラメータでなければなりません。メソッドx(String ... params)はx()として呼び出すことができ、メソッドy(String pram、String ... params)はy( "1")として呼び出すことができます
DamianLeszczyński-Vash

2
これもうまくいくといいのですが。myMethod( "one"、 "two"、 "three"、new String [] {"a"、 "b"、 "c" "});
2sb

2
メソッド0のパラメーターを指定できるのはなぜですか?それは、おそらくArrayIndexOutOfBoundsExceptionにつながります。今、あなたは常にそのケースを考慮に入れなければなりません。
OlleSöderström2013年

11
オプションだからです。0個以上の引数を処理するメソッドを適切に実装するためにオプションの引数を使用することを決定したのは開発者次第です。
kiswa 2013年

@OlleSöderström別の理由は、仮パラメーターがコンパイル時に配列に変換されることです。つまり、配列を渡しても同じ結果になります。配列の長さはコンパイル時に分からないため、少なくとも1つの要素を渡すという制限は、を呼び出すだけで回避できますsomeMethod(new SomeType[] { })。それはハックでしょうね。
MC皇帝

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

この回答は、キスワとロレンゾの...とグラファンのコメントからも大いに借りています。


13
コードがバイトコードに到達すると、それ配列になります。それ以外はすべて、コンパイラだけでサポートされる構文です。
ドナルフェロー2010

この回答は、編集を正しく読んだ場合、kiswaとLorenzoから大いに借りています。
Matt Mitchell、

3
@Graphは、回答をそのままにするよりも、回答を編集してより正確にする方が適切です。そして、別の答えがあなたの改善の源であるならば、そうです。少なくとも彼はそれについて正直です(そして私は彼が彼を助けた他の答えを支持したと思います...そうですか?)。

1
@私が指摘した後、彼は正直でしょうか?見てくれてありがとう。
マットミッチェル

23

それはVarargsです :)

可変長引数の可変長引数は、メソッドが可変数の引数(ゼロ以上)を受け入れることを可能にする機能です。可変引数を使用すると、可変数の引数を取る必要があるメソッドを簡単に作成できるようになりました。可変引数の機能がJava 5に追加されました。

可変引数の構文

可変引数は、データ型の後に3つの省略記号(3つのドット)で保護されます。その一般的な形式は次のとおりです。

return_type method_name(data_type ... variableName){
}  

可変引数の必要性

Java 5より前は、可変数の引数が必要な場合、それを処理する方法は2つありました。

メソッドが取ることができる引数の最大数が小さく、既知である場合、メソッドのオーバーロードされたバージョンが作成される可能性があります。メソッドがとることができる引数の最大数が大きいか不明な場合、アプローチはそれらの引数を配列に入れ、配列をパラメーターとして受け取るメソッドに渡すことでした。これらの2つのアプローチはエラーが発生しやすかった-毎回パラメーターの配列を作成し、維持するのが難しい-新しい引数を追加すると、新しいオーバーロードメソッドが作成される可能性があるため。

可変引数の利点

よりシンプルなオプションを提供します。オーバーロードされたメソッドを記述する必要がないため、コードが少なくて済みます。

可変引数の例

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

ここでは長さがメソッドに渡される引数の数を見つけるために使用されていることがプログラムからわかります。可変引数は暗黙的に配列として渡されるため、これは可能です。可変引数として渡される引数はすべて、可変引数に指定された名前で参照される配列に格納されます。このプログラムでは、配列名は値です。また、メソッドは異なる数の引数で呼び出され、最初に4つの引数、次に3つの引数、次にゼロの引数で呼び出されることに注意してください。これらの呼び出しはすべて、可変引数を取る同じメソッドによって処理されます。

可変引数による制限

メソッドでvarargsパラメーターを使用して他のパラメーターを指定することは可能ですが、その場合、varargsパラメーターはメソッドによって宣言された最後のパラメーターでなければなりません。

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

varargsのもう1つの制限は、varargsパラメーターが1つだけでなければならないことです。

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メソッドをオーバーロードしている間、呼び出しがあいまいになる場合があります。例を見てみましょう

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)およびdisplayData(int a, int ... values)

これらの2つのオーバーロードメソッドには、あいまいさが常にあります。


15

これは、可変引数(変数の引数)を渡すJavaの方法です。

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パラメータは1つに制限されており、複数のvar-artパラメータを持つことはできないことを知っておくことが重要です。たとえば、これは違法です。

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


2

android AsyncTaskの最も有名なメソッドの1つにある3つのドットの使用の明確な例を確認するための本当に一般的な方法(Googleアーキテクチャコンポーネントは言うまでもなく、RXJAVAのために今日はあまり使用されていません)、この用語を検索する数千の例を見つけることができます。3つのドットの意味を理解し、決して忘れないための最良の方法は、それらが共通言語と同じように...疑い...を表すことです。つまり、渡される必要があるパラメーターの数が明確ではなく、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[]、あなたはちょうどそれを言うことができませんでしたか?
スコットハンター

8
String[]引数は必要ですが(少なくとも空の配列)、String...そうではありません(上記の回答を参照)。
オーレル

0

他のよく書かれた回答に加えて、varagrs有用であるとわかった利点は、配列をパラメーター型として使用してメソッドを呼び出すと、配列を作成する手間が省けることです。要素を追加して送信します。代わりに、必要なだけの値でメソッドを呼び出すことができます。ゼロから多数まで。


0
  • 同じデータ型のゼロまたは複数のパラメーターを意味します。
  • これは、コンストラクターまたは関数の最後のパラメーターでなければなりません。
  • この型パラメーターは、それぞれのコンストラクターまたは関数で1つだけ持つことができます。

例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

構文:( トリプルドット...)-> 0個以上のオブジェクトを引数に渡すか、オブジェクト型の配列を渡すことができることを意味します。

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

定義: 1)Object ...引数は、オブジェクトの配列への参照です。

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.   
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.