Java에서 변수 인수가있는 메소드에 배열을 인수로 전달할 수 있습니까?
다음과 같은 함수를 만들 수 있기를 원합니다.
class A {
private String extraVar;
public String myFormat(String format, Object ... args){
return String.format(format, extraVar, args);
}
}
여기서 문제는이 args
같은 처리 Object[]
방법에있어서 myFormat
, 따라서 단일 인수입니다 String.format
내가 매일 싶습니다 동안 Object
의이 args
새로운 인수로 전달되어야한다. String.format
가변 인수를 가진 메소드이기도하기 때문에 이것이 가능해야합니다.
이것이 가능하지 않은 경우와 같은 방법이 String.format(String format, Object[] args)
있습니까? 이 경우 새 배열 extraVar
을 args
사용하여 해당 메소드에 전달할 수 있습니다.
variadic 메소드의 기본 유형은 function(Object... args)
입니다 function(Object[] args)
. Sun은 이전 버전과의 호환성을 유지하기 위해 이러한 방식으로 varargs를 추가했습니다.
그래서 당신은 단지 앞에 추가 할 수 있어야 extraVar
로 args
하고 전화 String.format(format, args)
.
예, a T...
는 a의 구문 설탕 일뿐 T[]
입니다.
JLS 8.4.1 형식 매개 변수
목록의 마지막 형식 매개 변수는 특별합니다. 유형에 따라 줄임표로 표시되는 가변 arity 매개 변수 일 수 있습니다 .
마지막 형식 매개 변수가 유형의 변수 arity 매개 변수 인 경우 형식
T
의 형식 매개 변수를 정의하는 것으로 간주됩니다T[]
. 이 방법은 가변 arity 방법입니다. 그렇지 않으면 고정 된 arity 방법입니다. 변수 arity 메소드의 호출에는 공식 매개 변수보다 더 많은 실제 인수 표현식이 포함될 수 있습니다. 변수 arity 매개 변수 앞의 형식 매개 변수에 해당하지 않는 모든 실제 인수 표현식이 평가되고 결과가 메소드 호출에 전달 될 배열에 저장됩니다.
다음은 설명하는 예입니다.
public static String ezFormat(Object... args) {
String format = new String(new char[args.length])
.replace("\0", "[ %s ]");
return String.format(format, args);
}
public static void main(String... args) {
System.out.println(ezFormat("A", "B", "C"));
// prints "[ A ][ B ][ C ]"
}
그리고 네, 위의 main
다시 때문에 방법은 유효 String...
단지입니다 String[]
. 또한 배열은 공변량이므로 a String[]
는 a Object[]
이므로 ezFormat(args)
어느 쪽이든 호출 할 수 있습니다 .
또한보십시오
Varargs gotchas # 1 : 추월 null
varargs가 해결되는 방법은 매우 복잡하며 때로는 놀라 울 수도있는 일을합니다.
이 예제를 고려하십시오.
static void count(Object... objs) {
System.out.println(objs.length);
}
count(null, null, null); // prints "3"
count(null, null); // prints "2"
count(null); // throws java.lang.NullPointerException!!!
varargs가 해결되는 방식으로 인해 마지막 명령문은로 호출되며 objs = null
물론 발생 NullPointerException
합니다 objs.length
. null
varargs 매개 변수에 하나의 인수 를 제공 하려면 다음 중 하나를 수행하십시오.
count(new Object[] { null }); // prints "1"
count((Object) null); // prints "1"
관련 질문
다음은 varargs를 다룰 때 사람들이 질문 한 몇 가지 예입니다.
Vararg gotchas # 2 : 추가 인수 추가
알다시피, 다음은 "작동하지 않습니다":
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(myArgs, "Z"));
// prints "[ [Ljava.lang.String;@13c5982 ][ Z ]"
varargs가 작동하는 방식 때문에 ezFormat
실제로 첫 번째는 a String[]
이고 두 번째는 a String
입니다. 배열을 varargs에 전달하고 해당 요소를 개별 인수로 인식하고 추가 인수를 추가 해야하는 경우 추가 요소를 수용하는 다른 배열 을 만들 수밖에 없습니다 .
유용한 도우미 메소드는 다음과 같습니다.
static <T> T[] append(T[] arr, T lastElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
arr[N] = lastElement;
return arr;
}
static <T> T[] prepend(T[] arr, T firstElement) {
final int N = arr.length;
arr = java.util.Arrays.copyOf(arr, N+1);
System.arraycopy(arr, 0, arr, 1, N);
arr[0] = firstElement;
return arr;
}
이제 다음을 수행 할 수 있습니다.
String[] myArgs = { "A", "B", "C" };
System.out.println(ezFormat(append(myArgs, "Z")));
// prints "[ A ][ B ][ C ][ Z ]"
System.out.println(ezFormat(prepend(myArgs, "Z")));
// prints "[ Z ][ A ][ B ][ C ]"
Varargs gotchas # 3 : 프리미티브 배열 전달
"작동하지 않습니다":
int[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ [I@13c5982 ]"
Varargs는 참조 유형에서만 작동합니다. 오토 박싱은 기본 배열에는 적용되지 않습니다. 다음과 같이 작동합니다.
Integer[] myNumbers = { 1, 2, 3 };
System.out.println(ezFormat(myNumbers));
// prints "[ 1 ][ 2 ][ 3 ]"
배열을 전달해도 괜찮습니다. 사실 같은 정도입니다.
String.format("%s %s", "hello", "world!");
와 같다
String.format("%s %s", new Object[] { "hello", "world!"});
기본 구문은 vararg 매개 변수 의 배열을 기대하기 때문에 컴파일러는 구문 설탕입니다. 컴파일러는 첫 번째 것을 두 번째로 변환합니다 .
보다
jasonmp85는 다른 배열을에 전달하는 것에 적합합니다 String.format
. 배열의 크기는 일단 구성되면 변경할 수 없으므로 기존 배열을 수정하는 대신 새 배열을 전달해야합니다.
Object newArgs = new Object[args.length+1];
System.arraycopy(args, 0, newArgs, 1, args.length);
newArgs[0] = extraVar;
String.format(format, extraVar, args);
나는 같은 문제가 있었다.
String[] arr= new String[] { "A", "B", "C" };
Object obj = arr;
그런 다음 obj를 varargs 인수로 전달했습니다. 효과가있었습니다.
'Programing' 카테고리의 다른 글
Bash 함수의 반환 값 (0) | 2020.04.04 |
---|---|
tensorflow에서 이름 범위와 변수 범위의 차이점은 무엇입니까? (0) | 2020.04.04 |
.NET EXE를 읽을 수있는 C # 소스 코드로 어떻게 디 컴파일합니까? (0) | 2020.04.04 |
C # Using 블록은 무엇이며 왜 사용해야합니까? (0) | 2020.04.04 |
문자열이 유니 코드인지 아스키인지 어떻게 확인합니까? (0) | 2020.04.04 |