2016-06-27 1 views
1

How to use TypeToken to get type parameter?을 추적하면 팩토리 메서드를 사용하여 클래스를 인스턴스화하면 TypeToken은 더 이상 제네릭 형식 매개 변수를 캡처 할 수 없습니다.팩토리 메서드가 사용되는 경우 TypeToken이 제네릭 형식을 캡처하지 못하는 이유는 무엇입니까?

import com.google.common.reflect.TypeToken; 

public class Test<E extends Enum<E>> { 

    private static enum MyEnum { 
     FIRST, 
     SECOND 
    }; 

    private final TypeToken<E> enumType = new TypeToken<E>(getClass()) { 
    }; 

    public static void main(String[] args) { 
     Test<MyEnum> container = new Test<MyEnum>() { 
     }; 
     System.out.println("constructor: " + container.enumType.getRawType()); 
     System.out.println("factory : " + build(MyEnum.class).enumType.getRawType()); 
    } 

    public static <E extends Enum<E>> Test<E> build(Class<E> type) { 
     return new Test<E>() { 
     }; 
    } 
} 

위 예제의 출력 :

constructor: class Test$MyEnum 
factory : class java.lang.Enum 

는 왜이 작품과는이 고정 될 수 있는가?

+3

다시 입력하십시오. 'build' 호출에 대해 유추되는'MyEnum' 유형은 메소드 구현 내부로 전달되지 않습니다. 익명 클래스는 타입 변수 'E'로 매개 변수화됩니다. 그것은 런타임에 그 사실을 알 수있는 전부입니다. (그리고 그것의 범위입니다.) –

+0

'Test'의 생성자에 type 매개 변수의 클래스 유형을 전달하고'TypeToken.of (cls)'를 사용하여 클래스 유형에서 직접'enumType'에 대한'TypeToken'을 구성 할 수 있습니다. – msandiford

+0

@SotiriosDelimanolis이 답변을 회신 메일로 보내 주시면 (해결 방법이 있음) 언제든지 허용으로 표시하겠습니다. – Gili

답변

1

아무도 공식적인 대답에 자신의 의견을 변환 방해하지 않기 때문에, 내가 가서거야, 그리고 그렇게보고 : 자바는 일반적인 상위 클래스의 형식 매개 변수에 대한 정보를 유지

previously discussed으로. 유형 매개 변수가 메소드 (수퍼 클래스와 반대)와 연관되어 있으므로 런타임 값 <E>이 보유되지 않습니다.

public static Test<MyEnum> of() { 
    return new Test<MyEnum>() { 
    }; 
} 

와 팩토리 메소드를 대체하는 것은 올바른 값 결과,하지만 우리가 하드 코딩 된 열거 형을 사용하도록 강제하고 있기 때문에 분명히 이것은 팩토리 메소드의 목적을 망가 뜨리는 것입니다.

요약하면 TypeToken는 여기서 작동하지 않습니다.

public class Test<E extends Enum<E>> { 

    private static enum MyEnum { 
     FIRST, 
     SECOND 
    }; 

    private final Class<E> type; 

    public Test(Class<E> type) { 
     this.type = type; 
    } 

    public static void main(String[] args) { 
     Test<MyEnum> container = new Test<>(MyEnum.class); 
     System.out.println(container.type); 
     System.out.println(of(MyEnum.class).type); 
    } 

    public static <E extends Enum<E>> Test<E> of(Class<E> type) { 
     return new Test<>(type); 
    } 
} 
0

생성 된 유형을 사용하는 방법에 따라 다른 옵션이 실제로하는 ParameterizedType를 구현하는 경우 : 형식 매개 변수에 대한 정보를 유지하는 유일한 방법은 다음과 같이 Class<E>을 전달하는 것입니다. 기본적으로 TypeToken.getType()이 반환 할 내용입니다.

public static ParameterizedType parameterizedType(Class<?> rawType, Type... actualTypeArguments) { 
    return new ParameterizedType() { 
     @Override 
     public Type[] getActualTypeArguments() { 
      return actualTypeArguments; 
     } 

     @Override 
     public Class<?> getRawType() { 
      return rawType; 
     } 

     @Override 
     public Type getOwnerType() { 
      return null; 
     } 
    }; 
} 
+0

죄송합니다, 이해가 안됩니다. 이 질문은 테스트 케이스에 어떻게 맞습니까? 이 접근법이 출력을 수정하는 것을 보여주기 위해 테스트 케이스를 업데이트 할 수 있습니까? – Gili

+0

실제로 테스트하려고하는 내용에 따라 테스트 케이스가 완전히 맞지 않을 수도 있습니다. 동적으로 (!) 매개 변수화 된 유형을 작성하는 접근법입니다. TypeTokens는 정적 인 사례 만 재사용 할 수 있습니다. 내가이 접근법을 사용한 것은 잭슨 (Jackson)을 사용하여 동적으로 deserialze하거나 일반 인터페이스를 기반으로하는 cdi에서 콩을 쿼리하는 것입니다. –

+0

좋아요, 실제로 작동 중임을 나타내는 자체 포함 된 실행 가능 샘플을 제공하거나 링크하십시오. 이 컨텍스트없이 코드 스 니펫을 이해하는 데 어려움을 겪고 있습니다. – Gili

관련 문제