다음은 제네릭을 사용하여 형식 안전을 유지하면서 찾고있는 형식의 배열을 얻는 방법입니다 (다른 답변과 달리 Object
배열 을 반환 하거나 컴파일 타임에 경고를 표시 함).
import java.lang.reflect.Array;
public class GenSet<E> {
private E[] a;
public GenSet(Class<E[]> clazz, int length) {
a = clazz.cast(Array.newInstance(clazz.getComponentType(), length));
}
public static void main(String[] args) {
GenSet<String> foo = new GenSet<String>(String[].class, 1);
String[] bar = foo.a;
foo.a[0] = "xyzzy";
String baz = foo.a[0];
}
}
당신이 볼 수있는 경고없이 컴파일하고, 같은 main
당신의 인스턴스 선언 어떤 유형, GenSet
등, 당신은 할당 할 수있는 a
해당 유형의 배열에, 당신은에서 요소를 할당 할 수 a
배열 즉, 해당 유형의 변수 배열의 값이 올바른 유형입니다.
Java Tutorials 에서 설명한 것처럼 클래스 리터럴을 런타임 유형 토큰으로 사용하여 작동합니다 . 클래스 리터럴은 컴파일러에서의 인스턴스로 처리됩니다 java.lang.Class
. 하나를 사용하려면으로 클래스 이름을 따르십시오 .class
. 따라서 클래스를 나타내는 객체 String.class
로 작동 Class
합니다 String
. 또한 인터페이스, 열거 형, 모든 차원 배열 (예 :) String[].class
, 프리미티브 (예 :) int.class
및 키워드 void
(예 :)에서도 작동합니다 void.class
.
Class
자체는 일반적입니다 (로 선언 Class<T>
, 여기서 객체가 나타내는 T
유형을 Class
나타냄) . 의 유형은 String.class
입니다 Class<String>
.
따라서에 대한 생성자를 호출 할 때마다 인스턴스의 선언 된 유형의 GenSet
배열을 나타내는 첫 번째 인수에 대해 클래스 리터럴을 전달 GenSet
합니다 (예 : String[].class
for GenSet<String>
). 프리미티브는 유형 변수에 사용할 수 없기 때문에 프리미티브 배열을 얻을 수 없습니다.
생성자 내에서 메서드를 호출하면 메서드 cast
가 호출 Object
된 Class
객체가 나타내는 클래스로 전달 된 인수가 반환 됩니다. 정적 메소드 newInstance
를 호출하면 첫 번째 인수로 전달 된 객체와 두 번째 인수로 전달 된 길이로 표시되는 유형의 배열이 java.lang.reflect.Array
반환됩니다 . 메소드 호출 복귀 어레이의 구성 형태를 나타내는 객체에 의해 표현 (예를 들어 메소드가 호출되는 객체 에 대해 , 경우 생성 객체 배열을 나타내지 않음).Object
Class
int
getComponentType
Class
Class
String.class
String[].class
null
Class
마지막 문장은 완전히 정확하지 않습니다. 호출 String[].class.getComponentType()
반환 Class
클래스를 나타내는 객체 String
, 그러나 그것의 유형입니다 Class<?>
하지, Class<String>
당신은 다음과 같은 일을 할 수없는 이유이다.
String foo = String[].class.getComponentType().cast("bar"); // won't compile
객체 Class
를 반환하는 모든 메소드에 동일하게 적용됩니다 Class
.
이 답변에 대한 Joachim Sauer의 의견에 대해 (나는 스스로 의견을 제시 할만큼 평판이 충분하지 않습니다), 캐스트를 사용하는 예제 T[]
는 컴파일러가 유형 안전을 보장 할 수 없기 때문에 경고를 표시합니다.
Ingo의 의견에 관한 편집 :
public static <T> T[] newArray(Class<T[]> type, int size) {
return type.cast(Array.newInstance(type.getComponentType(), size));
}