2013-09-27 3 views
5

왜 이런 일이 발생하고 있습니까? 형식 결정 메서드에 익명의 제네릭 클래스를 전달하면 모두 좋다. 나는이 방법으로 개체를 전달한다면 - 콘솔 출력은 E.런타임 일반 유형 결정

public static void main(String[] args) { 

    printType(new ArrayList<Integer>() {}); 
    printType(new ArrayList<Integer>()); 

} 

public static void printType(final List<?> list) { 
    System.out.println(((ParameterizedType) list.getClass().getGenericSuperclass()).getActualTypeArguments()[0]); 
} 

콘솔은 다음과 같습니다

class java.lang.Integer 

E 

나에게 설명해주십시오.

+0

무엇을하려고합니까? –

+0

잘 목록의 타입 매개 변수를 인쇄하고 있습니다 –

+0

런타임에 유형의 매개 변수를 가져 오려고합니다. –

답변

7

첫 번째 호출은 ArrayList<Integer>의 익명 하위 클래스 인스턴스를 전달합니다. 그래서,이 비슷 :

class YourClass extends ArrayList<Integer> 

하고 같은 방법을 호출 :

printType(new YourClass()); 

귀하의 경우 YourClass의 일반 슈퍼 클래스 또는 익명 클래스를 ArrayList<Integer> 전용입니다. 그래서 그 결과는 분명합니다.


두 번째 경우는 ArrayList<Integer> 인스턴스를 전달하는 것입니다. 이 클래스의 정의는 다음과 같습니다.

public class ArrayList<E> extends AbstractList<E> 
     implements List<E>, RandomAccess, Cloneable, java.io.Serializable 

따라서 일반 수퍼 클래스는 AbstractList<E>입니다. 제네릭 형식 공유 같은 Class 인스턴스의

인스턴스화 : ArrayList의 모든 인스턴스가 런타임에 동일한 클래스를 공유하는

참고 :

new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass(); 

위의 비교는 당신에게 true을 줄 것이다. 모두 있기 때문에 getClass() 호출 당신에게 다시 제공 :

class java.util.ArrayList 

JLS 8.1.2: Generic Classes and Type Parameters를 참조하십시오

일반적인 클래스 선언은 매개 변수 유형 세트를 정의 (§4.5), 유형의 가능한 각 호출에 대해 하나 매개 변수 섹션 형식 인수. 이러한 매개 변수가있는 모든 유형은 런타임에 동일한 클래스를 공유합니다.

Vector<String> x = new Vector<String>(); 
    Vector<Integer> y = new Vector<Integer>(); 
    boolean b = x.getClass() == y.getClass(); 

의 값 true 유지 가변 b 될 것이다 코드를 실행 예컨대

. 즉

getGenericSuperClass() 방법은 당신에게 당신의 클래스를 인스턴스화하는 동안 사용하는 실제의 형태 인수하지만 확장 된 클래스에서 사용되는 형식 매개 변수를 제공하지 않습니다. 이제 java.util.ArrayList의 일반 수퍼 클래스는 AbstractList<E>입니다. 따라서 형식 매개 변수는 E이됩니다.