2011-04-26 4 views
11

제네릭 형식의 "실제"클래스는 어떻게 구할 수 있습니까?제네릭 형식의 "실제"클래스 가져 오기

public class MyClass<T> { 
    public void method(){ 
     //something 

     System.out.println(T.class) //causes a compile error, I wont the class name 

     //something 
    } 
} 

경우 T = 정수

출력 :

java.lang.Integer 

경우 T = 문자열

출력 :

java.lang.String 

감사합니다.

+2

리플렉션을 통해 확인할 수 있습니다. 하지만 일반 유형에 따라 데이터를 다르게 처리해야하는 경우에는 잘못 처리 한 것입니다. 당신은해서는 안됩니다. 그렇게 할 필요가 없다면 생각만큼 일반적인 것이 아니며, 이는 수업에 문제가 있음을 의미합니다. – corsiKa

+1

@glowcoder :이 항목이 유효 할 수있는 한 가지 예제는 제네릭 형식의 정적 속성에 액세스하는 것입니다. 하나의 해결 방법은'T obj;'와 같이 실제로 사용하지 않는 인스턴스를 정의하는 것입니다. 나중에 'obj.static_property'라고 말할 수 있습니다. 또한'((T) null) .static_property'를 할 수 있습니다. – mellamokb

+0

만약 당신이 그 타입의 객체를 가지고 있다면, 그 객체에 대해'getClass' 메쏘드를 호출 할 수 있습니다. 도움이되는지 확실하지 않습니다. –

답변

21

처럼 사용하고, 그 다음에 당신이 그 변수의 클래스를 인쇄 할 수 설정할 수 발생합니다. 제네릭 형식으로받은 인스턴스에 'getClass()'에 의존하는 접근 방법

public class Test<T> { 

    T var; 

    public static void main(String[] args) { 
     Test<Integer> a = new Test<Integer>(); 
     System.out.println(a.boo()); 
     a.setVar(new Integer(10)); 
     System.out.println(a.boo()); 
    } 

    public String boo() { 
     if (var == null) { 
      return "Don't know yet"; 
     } 
     return var.getClass().getSimpleName(); 
    } 

    public void setVar(T var) { 
     this.var = var; 
    } 

    public T getVar() { 
     return var; 
    } 
} 
+0

X가 T를 확장하는 클래스 X의 인스턴스에 var가 설정된 경우를 생각해보십시오. boo()는 T 대신 X를 인쇄합니다. – jackrabbit

12

수 없습니다. 정보는 컴파일 타임에 코드에서 제거됩니다.이 프로세스를 유형 삭제라고합니다. 자세한 내용은 여기를 참조하십시오. Type Erasure

편집 : 죄송합니다. 내 정보가 런타임에로드되지 않습니다.

+1

잘, 사실은 아니지만 클래스 파일에 클래스 또는 메소드 속성으로 있습니다. 런타임시 메모리에로드되지 않습니다. – MeBigFatGuy

+0

@MeBigFatGuy : 감사합니다! 위에서 언급 한 내용을 바로 잡으십시오. –

3

상황에 따라 그럴 수 없습니다. 그러나 이러한 유형의 유형에 대해 슈퍼 유형 토큰을 사용할 수 있습니다. http://gafter.blogspot.com/2006/12/super-type-tokens.html

이러한 구현 예는 Jackson json 처리 라이브러리의 TypeReference 클래스입니다.

이 고급 물건과 다른 사람이 설명했듯이, 그 방식으로 그것을 할 수 없습니다 ;-)

4

를 알고 싶어보다 아마 더 있지만 그것이 일반적으로 자바 달성 어떻게입니다. 당신이 당신의 클래스 형 T의 인스턴스 변수가있는 경우

public class MyClass<T> { 
    public void method(Class<T> clazz) { 
     // something 

     System.out.println(clazz.getName()); 

     // something 
    } 
} 

은 당신이

new MyClass<String>().method(String.class); 
0

참고 반드시 일반 유형이 아닌 객체의 실제 타입 얻을 것이다 - 유형이 될 것이다 바이 발신자가 인스턴스를 알았습니다.

예를 들어, 호출자가 인터페이스로 객체를 처리하는 경우를 생각해보십시오. 일반 구문에 전달할 때 제네릭 형식은 인스턴스의 실제 클래스가 아니라 인터페이스가됩니다.

public class Pair<U,V> 
{ 
    public final U first; 
    public final V second; 
    public static <U,V> Pair<U,V> of (U first, V second) 
    { 
     return new Pair<U,V> (first, second); 
    } 
    protected Pair (U first, V second) 
    { 
     this.first = first; 
     this.second = second; 
    } 
} 

우리는 돌아갑니다 'Pair.of()'공장 기능을 수정하는 방법을 고려했다 :

는 두 개의 객체 참조가 POJO를 통해 반환 할 수 있도록 다음의 예 "쌍"클래스를 고려 U와 V가 모두 Comparable 인 경우 Comparable Pair 파생 클래스입니다. 그러나 '첫 번째'와 '두 번째'가 instanceof를 사용하여 비교 가능한지 여부를 알 수는 있지만 'U'와 'V'자체는 비교할 수 없다는 것을 알 수 있습니다.

이 기능을 사용하려면 정확한 쌍의 쌍이 쌍으로 반환됩니다.of()는 이 아닌 실제 유형에 따라 달라야합니다.

관련 문제