2011-10-23 3 views
2

제목이 잘못되었거나 더 나은 지식을 가진 사람이 편집 할 수 있습니다.지도에 제네릭 매개 변수를 보낼 수 있습니까?

나는 T는 Entity라는 클래스에 서브 클래스입니다보다 구체적 Map<String, T>, GSON를 사용하여 JSON 파일을 구문 분석하고지도로 데이터를 반환하는 방법 parseFromJSONMap을 만들려고합니다. 서브 클래스 중 두 개는 지금까지 정의되었으므로 CreatureHero이지만 나중에있을 수 있습니다. 내가

parseFromJSONMap(file, Creature.class) 

를 호출하는 경우 그래서 그것은 Map<String, Creature>를 반환해야 내가

parseFromJSONMap(file, Hero.class) 

를 호출 할 경우 반환해야 Map<String, Hero>

이 방법은 지금처럼 (그것은 단지 작품 모습입니다 생물을위한) :

public static <T extends Entity> Map<String, T> parseFromJSONMap(File file, Class<T> clazz) throws FileNotFoundException 
{ 
    Type type = new TypeToken<HashMap<String, Creature>>(){}.getType(); 
    return gson.fromJson(new FileReader(file), type); 
} 

대신에 Creature, T을 입력하고 싶습니다. 내가 그렇게하고 그렇게

Map<String, Creature> test = Entity.parseFromJSONMap(somefile, Creature.class); 

처럼 호출하면 나는 java.lang.Object cannot be cast to heroes.model.Creature

내가 할 수 원하는 무엇을 얻을?

편집 : test의 모든 메서드 (예 : test.get("someCreature"))를 호출하면 예외가 발생하므로 런타임 예외입니다.

+0

당신이 얻는 stacktrace를 추가하는 것이 가치가 있습니다. – Matt

+0

저는 그것이 유일한 예외라고 생각합니다. 왜냐하면 내가 가지고있는 것은 'Entity.parseFromJSONMap'을 호출하는'Creature '의 임시 메인 메소드이기 때문입니다. 스레드 "main"예외 java.lang.ClassCastException : java.lang.Object는 heroes.model.Creature.main (heroes.model.Creature.main)에 heroes.model.Creature \t으로 캐스팅 할 수 없습니다.java : 131)' –

답변

1

당신이 이것을 터트 리는 것을 의미합니까?

public static <T extends Entity> Map<String, T> parseFromJSONMap(File file, Class<T> clazz) throws FileNotFoundException 
{ 
    Type type = new TypeToken<HashMap<String, T>>(){}.getType(); 
    return gson.fromJson(new FileReader(file), type); 
} 

귀하의 문제

당신이 TypeToken 그렇지 않으면 어떻게 그것을 표현해야 유형을 알 수 있습니다 만들 때 형식 인수 콘크리트를 만들 필요가있다? 삭제가 replacing type parameters by their leftmost bound이고 그 중 super type token (Guice & Gson 및 기타 여러 곳에서 사용되는 TypeToken이 무엇인지)은 기본적으로 리플렉션을 통해 수퍼 클래스의 매개 변수화 된 유형 정보에 액세스 할 수있는 트릭입니다. 또한 유의 javadoc에서는

이 구문은 Class<?> 또는 List<? extends> CharSequence> 같은 와일드 카드 매개 변수가 형 리터럴을 생성하는 데 사용할 수 없습니다 말했다.

이것은 기본적으로 사용자 상황입니다. 내가 아는 유일한 방법은 프로그래밍 방식으로 형식 토큰을 만드는 것입니다. 예를 들어 Method.getGenericReturnType을 통해 또는 Guice가 형식 토큰을 사용하는 방식을 보면, 언뜻보기에는이 물건을 알아내는 유틸리티 메소드가 풍부 해집니다. 이를 수행하는 방법의 예가 this question인데, 일부 guice 클래스를 사용합니다.하지만 guice 소스를 살펴보면 실제로 무슨 일이 일어나는지 분명하게 알 수 있습니다.

+0

필자는 필요한 것보다 많은 라이브러리를 포함하고 싶지 않습니다. 'parseFromJSONMap'을 Entity의 Normal Map을 리턴 한 추상적 메소드로 만든 다음 각 서브 클래스가 그것을 구현하도록하는 것이 더 합리적일까요? –

+0

은 간단하고, 장황한 방법으로 문제를 해결할 수 있습니다. 제공하는 유형을 항상 제어하면됩니다. 유일한 대안은이 기능을 제공하기 위해 사용중인 라이브러리를 확장하는 것 같습니다. – Matt

+0

이것이 "추상적 인 정적"수정자를 갖고 싶은 경우 중 하나라고 생각합니다. 모든 것을 시작하는 GameResourceManager 클래스를 사용하여 일시적으로 문제를 해결했습니다. GRM은 먼저 크리쳐 폴더의 각 json 파일을 분석하여 Creatures를 표현한 다음 영웅 등을 나타내는 영웅 폴더에 넣습니다. 이것이 좋은 디자인인지는 모르겠지만 개별 클래스의 책임을 단일 클래스로 옮깁니다 클래스와 거기 아마 당신이 말하는 것처럼, 내가 만들고있는 타입에 대한 더 많은 제어권을 가질 것입니다. –

관련 문제