2010-12-16 8 views
0

다음 코드 단편은 유닛 테스트에서이 코드를 실행할 때 의미가 있습니다. '>>>>'로 표시된 줄에서 ClassCastException (Object는 String으로 캐스트 할 수 없음)을 얻습니다. 이러한 유형의 작업을 일반 작업에서 수행 할 수 있습니까?Java generics 및 배열

public class ArrayUtils<E> { 

    public static <E> E[] appendToArray(E[] array, E item) { 
     E[] result = (E[])new Object[array.length+1]; 
     for(int i=0; i < array.length; i++) { 
      result[i] = array[i]; 
     } 
     result[result.length-1] = item; 
     return result; 
    } 

} 

    @Test 
    public void testAppendToArray() { 
     String[] array = new String[1]; 
     array[0] = "a"; 

     assertSame("Array is not correct length.", 1, array.length); 
>>>> String[] appendToArray = ArrayUtils.<String>appendToArray(array, "b"); 
     assertSame("Array is not correct length.", 2, appendToArray.length); 
    } 
+0

어떤 이유로이'E는 [] 결과 = (E []) 새 개체가 있습니까 [사항 Array.length + 1]; ''E [] result = new E [array.length + 1];'(Java Generics를 많이 수행하지는 않았지만 아마도 금지되어있을 것입니다.) –

+0

@ Noon Silk, E는 클래스가 아니기 때문에 금지됩니다. 그러나 TypeParameter. –

+0

솔직히 참조 배열을 남겨 두십시오. –

답변

1

당신이 StringObject을 주조하고, IOW, 상속 하나에 슈퍼 클래스입니다. 항상 금지되어 있습니다. AlexR이 제안한대로 Arrays.newInstance()을 사용하십시오. 그러나이 경우 사용자는 여기로 객체의 클래스를 통과해야합니다 :

ArrayUtils.<String>append(array, "b", String.class); 

난 당신이 동적으로 확장 배열의 표준 동작을 구현하는 시도하지 않는 것이 좋습니다 : 이미 ArrayList 클래스에서 구현되고있다. 제네릭을 다루는 방법을 배우려면 소스를 체크 아웃 할 수 있습니다.

5

새 Object []를 사용하여 배열을 만들면 안됩니다. 대신 Array.newInstance(Class clazz, int length)을 사용해야합니다.

0

이 코드는 무엇인지 모르지만 가비지 수집기에 부담이됩니다. 하나의 요소를 추가하기 위해 새 배열을 할당하기 때문에. 이 경우 List 구현을 사용해야합니다 (예 : ArrayList).

0

제네릭 형식 (E)과 관련된 정보가 런타임에 전달되지 않으므로 Java에서 제네릭 형식의 배열을 동적으로 만들 수있는 방법이 없으므로 만들려는 배열의 유형을 알 수있는 방법이 없습니다 .

내가 one used in collections library

T[] java.util.List.toArray(T[] array) 

방법과 유사한 솔루션을 제안 문제를 해결합니다. 즉, appendToArray 함수 안에 새 배열을 만드는 대신 외부에서 전달하십시오.

public static <E> E[] appendToArray(E[] array, E item, E[] newArray) { 
    ... your code ... 
} 

@Test 
public void test(){ 
    appendToArray(array, "b", new String[array.length+1]); 
} 

나는이 다른 솔루션처럼 좋은 보이는하지 않습니다 알고 있지만, 반사에 의존하지 않기 때문에 그것은 안전 입력, 그리고 더 나은 성능을 가지고 때문입니다. 이

T[] java.util.List.toArray() 
0

해당하는 반사 다른 사람이 말했듯이, 당신이 올바른 유형의 배열의 인스턴스를 생성 Array.newInstance()를 사용해야가의 이상이 매우 이유로 당신은

T[] java.util.List.toArray(T[] array) 

방법을 사용하는 것이 좋습니다. 더 유용한 것은 원래 배열의 클래스에서 필요한 구성 요소 유형을 얻을 수 있다는 것입니다.

또한 System.arraycopy()을 사용하여 복사를 단순화했습니다.

public static <E> E[] appendToArray(E[] array, E item) { 
    E[] result = (E[])java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), array.length+1); 
    System.arraycopy(array, 0, result, 0, array.length); 
    result[result.length-1] = item; 
    return result; 
} 

자바 1.6에서, 당신은이 작업을 수행 할 수 있습니다

public static <E> E[] appendToArray(E[] array, E item) { 
    E[] result = java.util.Arrays.copyOf(array, array.length+1); 
    result[result.length-1] = item; 
    return result; 
}