2012-10-29 4 views
2

이 제네릭 클래스를 만들거나 삽입 할 때 배치되는 제네릭 형식 인수에서 클래스 형식을 사용하는 제네릭 클래스를 어떻게 만들 수 있습니까? 내 목표는 예를 들어 MyGeneric<User>을 지정하는 것이므로 일반 클래스는 모든 메서드 호출에서 User 클래스를 사용할 수 있어야합니다. generic의 생성자에 User.class을 명시 적으로 추가하지 않아도됩니다. 같은유형 인수만으로 일반 클래스를 만드시겠습니까?

뭔가 :

class MyGeneric<T> { 
    public MyGeneric() { 
     someService.create(Class<T>, someString); 
    } 
} 

class Usage { 
    @Inject 
    MyGeneric<User> myuser; 
} 

이 propertly 어떻게하는 것인가?

+0

이유 :

또한 같은 익명 클래스와 함께 사용할 수있는? 이것은 MyGeneric이 T의 메소드를 사용하는 것을 허용하지 않을 것입니다. MyGeneric은 T의 상한의 메소드 만 사용할 수 있습니다. – ignis

답변

0

당신이 할 수있는 일은 수퍼 클래스에 인스턴스화 코드를 작성한 다음 각 일반 제네 타입에 대해 인스턴스화 코드를 작성하는 것입니다 (서브 클래스에는 코드가 거의 또는 전혀 필요하지 않지만 서브 클래스는 유형을 피할 수있는 유일한 방법이기 때문에 필수입니다). 삭제) :

abstract class MyGeneric<T> { 

    private T instance; 

    public MyGeneric(String str) { 
     // grab the actual class represented by 'T' 
     // this only works for subclasses of MyGeneric<T>, not for MyGeneric itself ! 
     Class<T> genericType = (Class<T>) ((ParameterizedType)getClass().getGenericSuperclass()) 
       .getActualTypeArguments()[0]; 
     try { 
      // instantiate that class with the provided parameter 
      instance = genericType.getConstructor(String.class).newInstance(str); 
     } catch (Exception e) { 
      throw new IllegalArgumentException(e); 
     } 
    } 
} 

class MyUser extends MyGeneric<User> { 
    public MyUser() { 
     // provide the string to use for instantiating users... 
     super("userStr"); 
    } 
} 

class User { /*...*/ } 

편집 : 서브 클래스의 사용을 강제하기 위해 제네릭 클래스 abstract했다. ... 나는 이것이 당신이 얻을 수있는 최초의 목표에 가장 가까운 생각

new MyGeneric<User>("..string...") {}

2

런타임으로 인해 수행 할 방법이 없습니다 type erasure.

일반적으로 Class<T>이라는 인스턴스 (예 : type token)를 생성자에 전달하는 방법을 암시합니다. 코드 패턴을 감안할 때 이러한 접근 방식을 고수해야합니다.

0

다소 까다 롭습니다 만 예를 들어

public class ReiHashMap<K,V> extends HashMap<K,V> { 

    private final TypeLiteral<K> keyTL; 

    public ReiHashMap(TypeLit<K> keyTL) { 
     this.keyTL = keyTL; 
    } 

    @Override 
    public V get(Object o) { 
     if (!keyTL.getRawType().isAssignableFrom(o.getClass())) { 
      throw new IllegalArgumentException("object " + o + " (class "+ o.getClass() +")ist not of type " + keyTL); 
     } 
     return super.get(o); 
    } 
    ... 

이 런타임에 얻을의 인수의 유형을 확인할 수 있습니다 HashMaps을의 확장은 다음과 같습니다 TypeLiteral은 Guice에서 당신은 같은 일을 할 수 있습니다.