나는 varargs를 두려워한다. 무엇을 사용 해야할지 모르겠습니다.
게다가 사람들이 원하는만큼 많은 논쟁을하게하는 것은 위험합니다.
컨텍스트를 사용하기에 적합한 컨텍스트의 예는 무엇입니까?
나는 varargs를 두려워한다. 무엇을 사용 해야할지 모르겠습니다.
게다가 사람들이 원하는만큼 많은 논쟁을하게하는 것은 위험합니다.
컨텍스트를 사용하기에 적합한 컨텍스트의 예는 무엇입니까?
답변:
Varargs 는 불확실한 수의 객체 를 처리해야하는 모든 방법에 유용 합니다 . 좋은 예가 있습니다 String.format
. 형식 문자열은 여러 개의 매개 변수를 사용할 수 있으므로 원하는 수의 개체를 전달할 메커니즘이 필요합니다.
String.format("This is an integer: %d", myInt);
String.format("This is an integer: %d and a string: %s", myInt, myString);
좋은 경험 법칙은 다음과 같습니다.
"입력으로 T (T 형이 무엇이든)의 배열이 필요한 모든 메소드 (또는 생성자)에 varargs를 사용하십시오.
그렇게하면이 메소드를 쉽게 호출 할 수 있습니다 (필요하지 new T[]{...}
않음).
List<T>
이 인수가 입력 전용 인 경우 (즉, 목록이 메소드에 의해 수정되지 않은 경우) 인수 와 함께 메소드를 포함하도록이 규칙을 확장 할 수 있습니다 .
또한 f(Object... args)
API가 명확하지 않은 프로그래밍 방식으로 미끄러지기 때문에 사용을 자제 합니다.
예를 들어, DesignGridLayout 에서 사용 JComponent
하여 한 번의 호출 로 여러을 추가 할 수 있습니다 .
layout.row().grid(new JLabel("Label")).add(field1, field2, field3);
위의 코드에서 add () 메소드는로 정의됩니다 add(JComponent... components)
.
마지막으로, 그러한 메소드의 구현은 빈 vararg로 호출 될 수 있다는 사실을 처리해야합니다! 적어도 하나의 인수를 부과하려면 다음과 같은 추악한 트릭을 사용해야합니다.
void f(T arg1, T... args) {...}
메서드의 구현이 T... args
인수 목록에있는 것보다 덜 간단하기 때문에이 트릭을 추한 것으로 생각 합니다.
이것이 varargs에 대한 요점을 분명히하는 데 도움이되기를 바랍니다.
if (args.length == 0) throw new RuntimeException("foo");
를 추가하는 것을 고려 했습니까 ? (발신자가 계약을 위반 한 이후)
void f(T arg1, T... args)
런타임까지 기다릴 필요없이 인수없이 호출되지 않도록 항상 제안 합니다.
디버깅 목적으로 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를 사용하는 경우 서버는 필요하지 않다는 것을 인식하기 전에 배열에 배치해야합니다. 많은 시간이 절약됩니다.
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
추신 : 심지어 나는 그것을 abt하지 않았을 때 varargs를 사용하는 것을 두려워했습니다. 그러나 지금 나는 그것에 익숙합니다. "우리는 미지의 것을 알고, 미지의 것을 두려워한다"고 말했듯이 최대한 많이 사용하면 그것을 좋아할 것입니다. :)
Varargs는 Java 버전 1.5에 추가 된 기능입니다.
이것을 사용하는 이유는 무엇입니까?
어떻게 작동합니까?
주어진 인수로 배열을 만들고 배열을 메소드에 전달합니다.
예 :
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입니다
나는 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
배열이 일반적으로 (배열 대신 여러 개의 인수를 호출하는 경우) 컴파일러가 내부적으로 컴파일러에 의해 생성 된 새로운 객체이기 때문에 나중에 상태가 변경 될 수있는 모든 종류의 객체를 전달하는 것과 실제로 다르지 않습니다. 사용, 이것은 확실히 예기치 않은 행동입니다.
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 메서드를 오버로드해서는 안됩니다. 그렇지 않으면 프로그래머가 어떤 오버로드가 호출되는지 알아내는 것이 어려울 것입니다. "