2012-01-10 5 views
0

나는 abstract class Abstr<T>이고 연장자는 class Ext<T>입니다. 내가 확장명이 초기화되었으므로 그 유형을 반환 할 수있는 Abstr이 필요합니다. 지금까지 나는 유형을 생성자에 제공 한 다음이를 저장하도록 superconstructor를 호출하여이 작업을 수행했습니다. 하지만 이것 역시 반사회적으로 작용할 것입니다. 지금까지처럼 말했다 :Java의 수퍼 클래스 생성자에서 확장 제네릭 클래스의 제네릭 형식을 가져 옵니까?

public abstract class Abstr<T> { 

    private Class<T> type; 

    public Abstr(Class<T> _class) { 
     this.type = _class; 
    } 

} 

public class Ext<T> extends Abstr<T> { 

    public Ext(Class<T> _class) { 
     super(_class); 
    } 

} 

public void someMethod() { 
    Ext<String> ext = new Ext<String>(String.class); 
} 

다음 호출하는 생성자의 종류에 저장해야하는 추상 클래스의 기본 생성자를 호출합니다 연재 기본 생성자와 같은 생성자를 호출하는 저를 제거해야 반사를 사용 :

public Abstr() {  
    this.type = (Class<D>) this.getClass().getTheTypeParameter(); // something along these lines 
} 

감사합니다.

+0

질문은 무엇입니까? 왜 단순히 그것을 시도하고 볼 수 있습니까? – duffymo

+0

질문은 반사와 함께하는 방법입니다. 몇 줄의 코드 여야합니다 .. – Pete

+0

@ Pete : 실제로 'String.class' 유형을'Ext '로 전달하지 않고는 할 수 없습니다 –

답변

1

당신은 생성자에서 Class isntance을 통과하지만 선택의 여지가없는 (또는 다른 방법으로). type erasure로 인해 ClassT 인 것은 검색 할 수 없습니다. 이는 기본적으로 컴파일시에만 T을 런타임에 사용할 수 없다는 사실에 기인합니다.

1

일부 메소드에 new Ext<String>()이있는 경우 유형에 대한 반사 데이터가 없기 때문에 이는 항상 작동하지 않을 수 있습니다.

따라서 Ext<String> ext = new Ext<String>(String.class);은 런타임에 유형 정보를 잃어 버리므로 (효과적으로 지우기) Ext ext = new Ext(String.class);이됩니다.

private Ext<String> stringExt과 같은 필드 또는 StringExt extends Ext<String>과 같은 구체적인 하위 클래스가있는 경우 검색 할 수있는 리플렉션 데이터가 있습니다. 여기

는 반사 구상 서브 클래스의 데이터를 얻기 위해 사용할 수있는 몇 가지 소스와의 짧은 기사 (그리고 아마도 필드를,하지만 난 그것을 테스트하지 않았다) : 내가 말했듯이, 우리가 사용하고있는 http://www.artima.com/weblogs/viewpost.jsp?thread=208860

구체적인 서브 클래스에 대한 유형 매개 변수를 얻기 위해 해당 코드의 조정 된 버전.

그래서 우리는이 같은 뭔가를 당신이 정말로

public Class<T> getType() 

유사 Abstr의 방법이 필요하면

class AbstractDAO<T entityType> { 
    protected Class<?> entityClass; 

    protected AbstractDAO() { 
    //ReflectionUtil is our adjusted version of code in the link above 
    entityClass = ReflectionUtil.getTypeArguments(AbstractDAO.class, getClass()).get(0); 
    } 
} 

//Here entityClass is User.class 
class UserDAO extends AbstractDAO<User> { ... } 
3

일반 부모가 아닌 클래스가 아닌 경우에만 작동합니다. 대답이,하지만 너무 오래를 인용 내가 코드를 훔치는 것처럼하지 어울릴입니다 - 예는 더 읽기

class Trick<T> { 
    T t; 
} 

public class GenericTest { 
    public static void main(String[] args) { 
     Trick<Set<String>> trick = new Trick<Set<String>>() { 
     }; 

     // Prints "class org.acm.afilippov.GenericTest$1" 
     System.out.println(trick.getClass()); 
     // Prints "org.acm.afilippov.Trick<java.util.Set<java.lang.String>>" 
     System.out.println(trick.getClass().getGenericSuperclass()); 
    } 
} 

Reflecting generics 튜토리얼을 참조 할 것. 그래서 거기서 읽으십시오 :)

+0

그건 꽤 이상 해요. 런타임에 형식 범위를 가져올 수있는 안정적인 방법으로 보이지 않습니다. 여전히 흥미 롭지 만, –

+0

@ LukasEder 최악의 경우 : 런타임이 아닙니다. 당신이 읽을 수있는 타입 바운드는 컴파일 타임에 설정됩니다. 내부 클래스는 코드에서 명시 적으로 정의 된 구체적이고 비 제네릭 클래스 인'GenericTest $ 1 '입니다. 따라서 "런타임에"읽으려는 모든 유형 매개 변수에 대해 컴파일 할 때 클래스를 정의해야합니다. – alf

+0

그 미친 generics ... ;-) –

1

Abstr의 일반 유형은 T입니다.이 모든 것은 리플렉션을 통해 얻을 수 있습니다.

코드를 단순화하려면 다음을 작성하십시오.

public class Ext<T> extends Abstr<T> { 
    protected Ext(Class<T> _class) { 
     super(_class); 
    } 

    public static <T> Ext<T> of(Class<T> _class) { return new Exit<T>(_class); } 
} 

Ext<String> ext = Ext.of(String.class); 
관련 문제