2011-01-26 7 views
0

제네릭에 다음 문제가 있습니다. 나는 서브 클래스 BB가 슈퍼 클래스 B의 필드 중 하나 인 A의 서브 클래스의 인스턴스를 얻기를 원한다. 누군가이 문제를 처리하는 가장 좋은 방법을 말해 줄 수있다.Java Generics 문제

아래의 코드를 따라 가십시오. (여기 // 문제를보십시오.) 그것은 자명하며 어쨌든 그것을 단어로 쓰는 법을 모르겠습니다. 가 표시된 장소에서 형식 매개 변수 T의 인스턴스를 만들려면 당신이 원하는 것은 경우

public class A { 
String name; 
A(String name){ 
    this.name = name; 
} 
} 


public class AA extends A{ 
     String itchy 
AA(String name) { 
    super(name); 
       this.itchy = name+"_itchy"; 
} 
} 

public class B<T extends A> { 
T field; 
T getField(String name) throws InstantiationException, IllegalAccessException{ 
       //Problem here 
    field = // instance of AA; how do i do this? 
    return field; 
} 
} 

public class BB extends B<AA>{ 
public static void main(String[] args) throws InstantiationException, IllegalAccessException { 
    BB b = new BB(); 
    System.out.println(b.getField("It works").name); 
} 
} 
+0

문제를 이해하는 것은 매우 어렵습니다. –

답변

1

, 그것은 자바 제네릭 (때문에 type erasure에)와 불행히도 수 없습니다.

원하는 것이 다른 것이라면 명확히하십시오.

+0

경우에 따라 가능합니다. generic param 클래스가 추상 클래스 인 경우 리플렉션을 사용하여 유형을 검색 한 다음 인스턴스를 만들 수 있지만 위험합니다. –

0

완전한 예입니까? 어느 곳에서나 A 또는 AA의 인스턴스가 생성되지 않습니다. System.out 줄에 "It works_itchy"라고 인쇄하려면 최소한 AA의 인스턴스를 만들어야합니다.

public B(T aaInstance) { 
    this.field = T; 
} 

유형의 삭제의 때문에, 당신은 AA의 인스턴스에서를 만들 수 없습니다 :

0

T 당신은 어쩌면 생성자에서, AA의 인스턴스에 전달해야 할 클래스 B의 AA의 인스턴스를 나타냅니다 컴파일 후에 유형을 사용할 수 없으므로 런타임에서이를 수행하려고합니다.

1

나는 이것에 대한 factory 인터페이스를 사용합니다 :

ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass(); 
Class<?> cls = (Class<?>) pt.getActualTypeArguments()[0]; 
field = (T) cls.getConstructor(String.class).newInstance(name); 
return field; 
0

것이 가능 (그러나 정말 이상한)이다 BB가 구현을 제공하도록 강요하십시오.

0

또 다른 옵션은 T getField(String)를 떠나 (그리고 거기에 B에 대한) 추상적이고 :

public interface Factory<T extends AA> { 
T create(String name); 
} 

public class AAFactory implements Factory<AA> { 
AA create(String name) { 
    return new AA(name); 
} 
} 

public class B<T extends A> { 
B(Factory<T> factory) { 
    this.factory = factory; 
} 
Factory<T> factory; 
T field; 
T getField(String name) { 
    field = factory.create(name); 
    return field; 
} 
} 

public class BB extends B<AA>{ 
BB() { 
    super(new AAFactory()); 
} 
public static void main(String[] args) throws InstantiationException, IllegalAccessException { 
    BB b = new BB(); 
    System.out.println(b.getField("It works").name); 
} 
} 
0

B는 생성하는 클래스의 사본이 필요합니다. 서브 클래스는 이것을 생성자에 전달합니다.

public class B<T extends A> { 
final Class<T> classT; 
B(Class<T> classT) { classT=classT;) 
T field; 
T getField(String name) throws InstantiationException, IllegalAccessException{ 
       //Problem here 
    field = classT.newInstance(); 
    return field; 
} 
} 

public class BB extends B<AA>{ 
    BB() { super(AA.class); } 

public static void main(String[] args) throws InstantiationException, IllegalAccessException { 
    BB b = new BB(); 
    System.out.println(b.getField("It works").name); 
} 
}