Java, 매개 변수의 3 점


822

다음 방법에서 3 개의 점은 무엇을 의미합니까?

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

답변:


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

중요 사항 : 이 방법으로 전달 된 인수는 배열이 하나라도 있어도 항상 배열입니다. 분석법 본문에서 그렇게 다루어야합니다.

중요 사항 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")로 호출 될 수 있습니다.
Damian Leszczyński-Vash

2
이것이 효과가 있었으면 좋겠다. myMethod ( "one", "two", "three", 새 문자열 [] { "a", "b", "c" "});
2sb

2
메소드에 매개 변수 0을 부여 할 수있는 이유는 무엇입니까? 이것은 아마도 ArrayIndexOutOfBoundsException을 일으킬 것입니다. 이제는 항상이 경우를 고려해야합니다.
Olle Söderström 12

11
그들은 선택 적이기 때문에. 선택적 인수를 사용하여 0 개 이상의 인수를 처리하는 메소드를 올바르게 구현하기로 결정한 것은 개발자의 몫입니다.
kiswa

@ OlleSöderström 또 다른 이유는 형식 매개 변수가 컴파일 타임에 배열로 변환되기 때문입니다. 즉, 배열을 전달하면 동일한 결과가 생성됩니다. 컴파일 타임에 배열의 길이를 알 수 없으므로 최소한 하나의 요소를 전달하는 제한을 간단히 호출하여 무시할 수 있습니다 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]
    }
}

이 답변은 kiswa 's와 Lorenzo 's .. 그리고 Graphain의 의견에서 많이 차용됩니다.


13
코드는 바이트 안타 때 이다 어레이. 다른 모든 것은 컴파일러가 지원하는 구문입니다.
Donal Fellows

이 답변은 편집 내용을 올바르게 읽으면 kiswa와 Lorenzo의 많은 돈을 빌려줍니다.
매트 미첼

3
@Graph는 '답을 편집하고 혼자 남겨 두는 것보다 더 정확하게 만드는 것이 좋습니다. 그리고 또 다른 대답이 당신의 개선의 근원이라면, 그렇습니다. 적어도 그는 그것에 대해 정직합니다.

1
@ 충분히 지적한 후에 그는 정직합니다. 찾아 주셔서 감사합니다.
매트 미첼

23

Varargs입니다 :)

가변 길이 인수의 짧은 varargs는 메소드가 가변 개수의 인수 (0 이상)를 허용 할 수있는 기능입니다. varargs를 사용하면 가변 개수의 인수를 사용해야하는 메소드를 작성하는 것이 간단 해졌습니다. 변수 인수의 기능이 Java 5에 추가되었습니다.

varargs의 구문

Vararg는 데이터 유형 다음에 3 개의 줄임표 (3 개의 점)로 고정되며 일반적인 형식은

return_type method_name(data_type ... variableName){
}  

Varargs가 필요

Java 5 이전에는 가변 수의 인수가 필요한 경우이를 처리하는 두 가지 방법이있었습니다.

인수의 최대 수, 메소드가 작고 알려진 경우 오버로드 된 메소드 버전을 작성할 수 있습니다. 메소드가 취할 수있는 최대 인수 수가 크거나 알 수없는 경우 접근 방식은 해당 인수를 배열에 넣고 배열을 매개 변수로 사용하는 메소드에 전달하는 것입니다. 이 두 가지 접근 방식은 오류가 발생하기 쉬우 며 매번 매개 변수 배열을 구성하고 유지하기가 어려웠습니다. 새로운 인수를 추가하면 새로운 오버로드 된 메소드가 작성 될 수 있습니다.

Varargs의 장점

훨씬 간단한 옵션을 제공합니다. 오버로드 된 메소드를 작성할 필요가 없으므로 코드가 줄어 듭니다.

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에 지정된 이름으로 참조되는 배열에 저장됩니다. 이 프로그램에서 배열 이름은 값입니다. 또한 메소드는 다른 수의 인수로 호출되며, 먼저 4 개의 인수로 호출 한 다음 3 개의 인수로 호출 한 다음 0 개의 인수로 호출합니다. 이 모든 호출은 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동일한 유형의 하나의 매개 변수 및 매개 변수를 갖는 방법을 오버로드하면 동일한 방식으로 모호함-As Exp- displayData(int ... values)displayData(int a, int ... values)

이 두 가지 오버로드 된 메소드에는 항상 모호성이 있습니다.


15

이것은 varargs (변수 번호 인수) 를 전달하는 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 매개 변수가 하나로 제한되고 여러 개의 var-art 매개 변수를 가질 수 없다는 것을 알아야합니다. 예를 들어 이것은 불법입니다.

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


2

안드로이드 AsyncTask 의 가장 유명한 방법 중 하나에 존재하는 세 점의 사용에 대한 명확한 예를 보는 가장 일반적인 방법 (오늘날 Google 아키텍처 구성 요소는 말할 것도없고 RXJAVA로 인해 너무 많이 사용되지 않음), 이 용어를 검색하는 수천 가지 예를 찾을 수 있으며, 세 점의 의미를 이해하고 더 이상 잊지 않는 가장 좋은 방법은 공통 언어와 마찬가지로 ... 의혹을 표현하는 것입니다. 즉, 전달되어야하는 매개 변수의 수, 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에서 많은 것까지.


0
  • 동일한 데이터 유형의 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 ...)-> 0 개 이상의 객체를 인수에 전달하거나 객체 유형의 배열을 전달할 수 있음을 의미합니다.

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.   
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.