2011-10-22 2 views
15

Java 7에서는 수정 불가능한 varargs 매개 변수로 메소드를 컴파일 할 때 경고 메시지를 표시하지 않도록 @SafeVarargs 주석을 넣을 수 있습니다. Project Coin의 proposal은 메서드가 varargs 매개 변수와 동일한 유형의 요소 만 varargs 배열에 저장되도록 할 때 주석을 사용해야한다고 규정합니다.Java 7에서 단순화 된 Varargs 메소드 호출

안전하지 않은 방법의 예는 무엇입니까? 예를 들어

답변

21

foo() 안전받지 못하면 @SafeVarargs와 마킹 법에 의해 [2]

<T extends List<?>> void foo(T... args) 
{ 
    List<String>[] array2 = (List<String>[])args; 
    array2[0] = a_list_of_string; 
} 

void test2() 
{ 
    List<Integer>[] args = ...; // [1] 
    foo(args); 
    Integer i = args[0].get(0); // [2] 
} 

에 문제를 일으키는 배열 비 T를 저장할 수 있고, 당신이 있는지 컴파일러 약속 그런 장난 꾸러기 못해.


하지만 어떻게 [1]에서 일반 배열을 시작할 수 있습니까? Java는 일반적인 배열 생성을 허용하지 않습니다!

는 일반 배열 생성

유일한 공인 방법

foo(list_int_1, list_int_2) 

다음 어레이는 호출자에 액세스 할 수없는 가변 인자 메소드를 호출 할 때 발신자 [2] 어쨌든 상관 없다 수 없어 어떻게 foo() 배열로 엉망이.

는하지만 당신은 그것을 는 일반적인 배열

@SafeVarargs 
static <E> E[] newArray(int length, E... array) 
{ 
    return Arrays.copyOf(array, length); 
} 

List<String>[] array1 = newArray(10); 

@SafeVarargs 
static <E> E[] array(E... array) 
{ 
    return array; 
} 

List<String>[] array2 = array(list1, list2); 

그래서 우리가 결국 일반적인 배열을 만들 수 있습니다 리터럴 일반적인 배열을 생성하기 위해 백도어입니다, 그것에 대해 생각합니다. .. 바보 같은 자바, 우리가 그렇게하지 못하도록 막으려 고.

+1

varargs 메서드없이 일반 배열을 만들 수 있지만 [Array # newInstance (Class type, int length)] (http://tinyurl.com/3uzbb7v)를 사용하여 캐스트해야합니다. 철저한 답변 주셔서 감사합니다. – Jeffrey

+0

"단순화"는 아니지만 개선 된 힌트입니다. –

+0

이 예제를 시도해 본 결과, @SafeVarargs를 사용하거나 사용하지 않고 동작이 변경되지 않았습니다. 나는 아직도 경고를 받는다 "유형 안전 : 목록 ...의 일반적인 배열" – excalibur

관련 문제