it-swarm.dev

Java에서 언제 varargs를 사용합니까?

나는 varargs를 두려워한다. 무엇을 사용 해야할지 모르겠습니다.

또한 사람들이 원하는만큼 많은 논쟁을하게하는 것은 위험합니다.

컨텍스트를 사용하기에 적합한 컨텍스트의 예는 무엇입니까?

189
Harry Quince

Varargs불확정 한 수의 개체를 처리해야하는 모든 방법에 대해 유용한입니다. 좋은 예는 String.format 입니다. 형식 문자열은 임의의 수의 매개 변수를 사용할 수 있으므로 원하는 수의 개체를 전달하는 메커니즘이 필요합니다.

_String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
_
150
Andy White

좋은 경험 법칙은 다음과 같습니다.

"입력으로 T (T 형이 무엇이든)의 배열이 필요한 모든 메소드 (또는 생성자)에 varargs를 사용하십시오."(

이렇게하면 이러한 메소드를 쉽게 호출 할 수 있습니다 (new T[]{...} 필요 없음).

이 인수가 입력 전용 인 경우 (즉, 목록이 메소드에 의해 수정되지 않은 경우) List<T> 인수가있는 메소드를 포함하도록이 규칙을 확장 할 수 있습니다.

또한 f(Object... args)의 사용은 명확하지 않은 API를 사용하는 프로그래밍 방식으로 미끄러지기 때문에 사용하지 않는 것이 좋습니다.

예를 들어 DesignGridLayout 에서 사용했으며 한 번의 호출로 여러 JComponents를 추가 할 수 있습니다.

layout.row().grid(new JLabel("Label")).add(field1, field2, field3);

위 코드에서 add () 메소드는 add(JComponent... components)으로 정의됩니다.

마지막으로, 그러한 메소드의 구현은 빈 vararg로 호출 될 수 있다는 사실을 처리해야합니다! 적어도 하나의 인수를 부과하려면 다음과 같은 추악한 트릭을 사용해야합니다.

void f(T arg1, T... args) {...}

메소드의 구현이 인수 목록에 T... args을 갖는 것보다 덜 간단하기 때문에이 트릭을 추악하게 생각합니다.

이것이 varargs에 대한 요점을 분명히하는 데 도움이되기를 바랍니다.

78
jfpoilpret

디버깅을 위해 로그에 출력하기 위해 varargs를 자주 사용합니다.

내 앱의 거의 모든 클래스에는 debugPrint () 메소드가 있습니다.

private void debugPrint(Object... msg) {
    for (Object item : msg) System.out.print(item);
    System.out.println();
}

그런 다음 클래스의 메서드 내에서 다음과 같은 호출이 있습니다.

debugPrint("for assignment ", hwId, ", student ", studentId, ", question ",
    serialNo, ", the grade is ", grade);

내 코드가 작동한다고 만족하면 로그에 너무 많은 불필요한 정보가 포함되지 않도록 debugPrint () 메서드의 코드를 주석 처리하지만 debugPrint ()에 대한 개별 호출은 주석 처리하지 않은 채로 둘 수 있습니다. 나중에 버그를 발견하면 debugPrint () 코드의 주석 처리를 제거하고 debugPrint ()에 대한 모든 호출이 다시 활성화됩니다.

물론, 나는 varargs를 쉽게 피하고 대신 다음을 수행 할 수 있습니다.

private void debugPrint(String msg) {
    System.out.println(msg);
}

debugPrint("for assignment " + hwId + ", student " + studentId + ", question "
    + serialNo + ", the grade is " + grade);

그러나이 경우 debugPrint () 코드를 주석 처리 할 때 결과 문자열로 아무것도 수행되지 않더라도 서버는 여전히 debugPrint ()를 호출 할 때마다 모든 변수를 연결하는 데 어려움을 겪어야합니다. 그러나 varargs를 사용하는 경우 서버는 필요하지 않다는 것을 깨닫기 전에 배열에 배치해야합니다. 많은 시간이 절약됩니다.

34
bob

Varargs는 메소드에 전달할 인수의 수가 확실하지 않은 경우에 사용할 수 있습니다. 백그라운드에서 지정되지 않은 길이의 매개 변수 배열을 작성하며 이러한 매개 변수는 런타임에서 배열로 처리 될 수 있습니다.

다른 수의 매개 변수를 허용하도록 오버로드 된 메서드가있는 경우 메서드를 다른 시간에 오버로드하는 대신 varargs 개념을 사용할 수 있습니다.

또한 매개 변수 유형이 달라질 때 "Object ... test"를 사용하면 코드가 크게 단순화됩니다.

예를 들면 다음과 같습니다.

public int calculate(int...list) {
    int sum = 0;
    for (int item : list) {
        sum += item;
    }
    return sum;
}

여기서 간접적으로 int 유형 (목록)의 배열은 매개 변수로 전달되고 코드에서 배열로 처리됩니다.

더 나은 이해를 위해이 링크를 따르십시오 (이 개념을 명확하게 이해하는 데 많은 도움이되었습니다) : http://www.javadb.com/using-varargs-in-Java

추신 : 심지어 나는 그것을 믿지 않을 때 varargs를 사용하는 것을 두려워했습니다. 그러나 지금 나는 그것에 익숙합니다. "우리는 미지의 것을 알고, 미지의 것을 두려워한다"고 말했듯이 최대한 많이 사용하면 그것을 좋아할 것입니다. :)

12
Sarvan

Varargs는 Java 버전 1.5에 추가 된 기능입니다.

왜 이것을 사용해야합니까?

  1. 메소드에 전달할 인수의 수를 모르는 경우 어떻게합니까?
  2. 메소드에 무제한의 인수를 전달하려면 어떻게해야합니까?

작동 방식

주어진 인수로 배열을 만들고 배열을 메소드에 전달합니다.

예 :

public class Solution {



    public static void main(String[] args) {
        add(5,7);
        add(5,7,9);
    }

    public static void add(int... s){
        System.out.println(s.length);
        int sum=0;
        for(int num:s)
            sum=sum+num;
        System.out.println("sum is "+sum );
    }

}

출력 :

2

합계는 12

합계는 21입니다

11
Arun Prakash

나는 varargs 관련 두려움도 있습니다.

호출자가 명시 적 배열을 메소드에 전달하면 (여러 매개 변수가 아닌) 해당 배열에 대한 공유 참조를받습니다.

이 배열을 내부에 저장해야하는 경우 호출자가 나중에 변경하지 못하도록 먼저 복제 할 수 있습니다.

 Object[] args = new Object[] { 1, 2, 3} ;

 varArgMethod(args);  // not varArgMethod(1,2,3);

 args[2] = "something else";  // this could have unexpected side-effects

배열이 일반적으로 (배열 대신 여러 인수를 사용하여 호출하는 경우) 컴파일러가 내부적으로 컴파일러가 생성 한 신선한 객체이므로 안전하게 변경할 수 있기 때문에 이것은 나중에 상태가 변경 될 수있는 모든 종류의 객체를 전달하는 것과 다르지 않습니다. 사용, 이것은 확실히 예기치 않은 행동입니다.

5
Thilo

필자는 일종의 필터 객체를 사용할 수있는 생성자에 대해 varargs를 자주 사용합니다. 예를 들어 Hadoop 기반 시스템의 상당 부분은 항목 직렬화 및 직렬화 해제를 JSON으로 처리하고 각 항목을 가져 와서 수정 및 반환하거나 null을 반환하는 많은 프로세서를 적용하는 Mapper를 기반으로합니다. 거부합니다.

1
Kevin Peterson

Var-Args의 Java doc에서 var args의 사용법이 분명합니다.

http://docs.Oracle.com/javase/1.5.0/docs/guide/language/varargs.html

사용법에 대해서는 :

"varargs를 언제 사용해야합니까? 클라이언트는 API가 제공 할 때마다이를 활용해야합니다. 핵심 API에서 중요한 용도로는 리플렉션, 메시지 형식 및 새로운 printf 기능이 있습니다. API 디자이너는이를 사용해야합니다. 일반적으로 말하면 varargs 메서드를 오버로드해서는 안됩니다. 그렇지 않으면 프로그래머가 어떤 오버로드가 호출되는지 알아내는 것이 어려울 것입니다. "

1
Surendra