문제

제네릭이 도입되었으므로 Class가 매개변수화되어 List.class가 Class<List>를 생성합니다.이것은 분명합니다.

내가 알아낼 수 없는 것은 자체적으로 매개변수화된 유형의 클래스 인스턴스를 얻는 방법입니다.클래스<목록<문자열>>.이 스니펫에서처럼:

public class GenTest {
    static <T> T instantiate(Class<T> clazz) throws Exception {
        return clazz.newInstance();
    }
    public static void main(String[] args) throws Exception {
        // Is there a way to avoid waring on the line below
        // without using  @SuppressWarnings("unchecked")?
        // ArrayList.class is Class<ArrayList>, but I would like to
        // pass in Class<ArrayList<String>>
        ArrayList<String> l = GenTest.instantiate(ArrayList.class);
    }
}

나는 이 문제의 변형에 자주 직면하는데, 내가 뭔가를 놓친 것인지, 아니면 실제로 더 좋은 방법이 없는 것인지는 여전히 알 수 없습니다.제안해 주셔서 감사합니다.

도움이 되었습니까?

해결책

Class 클래스는 유형의 런타임 표현입니다.매개변수화된 유형은 런타임 시 유형 삭제를 거치기 때문에 Class의 클래스 객체는 Class<List<Integer>> 및 Class<List<String>>의 경우와 동일합니다.

.class 표기법을 사용하여 인스턴스화할 수 없는 이유는 이것이 클래스 리터럴에 사용되는 특수 구문이기 때문입니다.그만큼 자바 언어 사양 유형이 매개변수화될 때 특히 이 구문을 금지하므로 List<String>.class가 허용되지 않습니다.

다른 팁

클래스는 원시 유형인 클래스 로더에 의해 로드된 클래스를 나타냅니다.매개변수화된 유형을 나타내려면 java.lang.reflect.ParameterizedType을 사용하십시오.

나는 당신이 노력하는 것을 할 수 있다고 생각하지 않습니다.첫째, 인스턴스화 메소드는 매개변수화된 유형을 처리한다는 사실을 모릅니다(java.util.Date.class를 쉽게 전달할 수도 있음).둘째, 삭제로 인해 런타임에 매개변수화된 유형으로 특별히 특정한 작업을 수행하는 것이 어렵거나 불가능합니다.

문제에 다른 방식으로 접근하려는 경우 유형 추론과 같은 다른 작은 트릭을 사용할 수 있습니다.

public class GenTest
{
    private static <E> List<E> createList()
    {
        return new ArrayList<E>();
    }

    public static void main(String[] args)
    {
        List<String> list = createList();
        List<Integer> list2 = createList();
    }
}

당신이 할 수 있는 유일한 일은 인스턴스화하는 것이다. List<String> 곧장 그리고 전화해 getClass():

instantiate(new List<String>() { ... }.getClass());

다음과 같은 여러 추상 메소드가 있는 유형의 경우 List, 이거 좀 어색하네요.하지만 안타깝게도 하위 클래스 생성자를 호출하면(예: new ArrayList<String>) 또는 팩토리 메소드(Collections.<String>emptyList()) 작동하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top