2011-01-18 6 views
1

나는 특정 클래스의 배열 형 얻기 위해 다음과 같은 트릭을 사용Java의 Class.getArrayType?

@SuppressWarnings("unchecked") 
public static <T> Class<T[]> getArrayType(Class<T> componentType) { 
    String arrayClassName = "[L" + componentType.getName() + ";"; 
    try { 
     return (Class<T[]>) Class.forName(arrayClassName); 
    } catch (ClassNotFoundException e) { 
     throw new UnexpectedException("Can't get the array type for " + componentType, e); 
    } 
} 

을하지만,이 얻을 수있는 더 우아한 방법은 무엇입니까?

답변

5

아마도 Array.newInstance()을 사용하면 주어진 유형의 배열을 반환합니다.

return Array.newInstance(someClass, 0).getClass() 

당신이 원하는 무엇을 얻을 수 있습니다 : 같은 일을

.

희망이 있습니다.

@SuppressWarnings({"unchecked"}) 
public static <T> Class<T[]> getArrayType(Class<T> componentType) { 
    return (Class<T[]>) Array.newInstance(componentType, 1).getClass(); 
} 

당신은 경고를 벗어날 수 있지만 짧고 더 :

2

이 시도해보십시오.

+0

배열의 길이가 될 수 0 – finnw

+0

나는 아마이 어쨌든 작품과 내가 생각하지 않는 0과 청소기 보이는 것에 동의 @finnw 그것은 어떤 이상한 문제가 있습니다. 왜냐하면 배열에 대한 객체 할당이 여전히 존재하고 클래스 참조를 얻은 후에 할당이 즉시 해제되기 때문입니다. –

3

나는 결과가 Zach L하지만 memoize과 동일 할 것 :

import java.lang.reflect.Array; 
import java.util.concurrent.ConcurrentMap; 
import com.google.common.base.Function; 
import com.google.common.collect.MapMaker; 

// ... 

static Function<Class<?>, Class<?>> TO_ARRAY_FUNC = 
    new Function<Class<?>, Class<?>>() { 
     @Override 
     public Class<?> apply(Class<?> from) { 
      return Array.newInstance(from, 0).getClass(); 
     } 
    }; 

static ConcurrentMap<Class<?>, Class<?>> ARRAY_TYPE_MAP = 
    new MapMaker().weakKeys() 
        .weakValues() 
        .makeComputingMap(TO_ARRAY_FUNC); 

@SuppressWarnings("unchecked") 
public static <T>Class<T[]> getArrayType(Class<T> componentType) { 
    return (Class<T[]>) ARRAY_TYPE_MAP.get(componentType); 
} 
+0

글쎄 방금 스니퍼에서 배웠던 것 :-p –

+3

현대의 JVM은 탈출 탐지에 능숙하며 즉시 newInstance를 처리 할 것이므로 캐싱에 신경 쓰지 않을 것입니다. –