Можно ли отправить универсальный параметр на карту? - PullRequest
2 голосов
/ 23 октября 2011

Возможно, название написано плохо, и кто-то с большими знаниями мог бы его отредактировать.

Я хочу создать метод parseFromJSONMap, который анализирует JSON-файл, используя gson, и возвращает данные в виде карты, в частности, Map<String, T>, где T является подклассом для класса с именем Entity. На данный момент определены два подкласса, Creature и Hero, но могут быть и другие. Так что, если я позвоню

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"), так что это исключение времени выполнения.

1 Ответ

1 голос
/ 24 октября 2011

Ты имеешь в виду, что ты делаешь это, чтобы вызвать взрыв?

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, иначе как он может знать, какой тип он должен представлять? Помните, что стирание - это замена параметров типа их самой левой границей , и что маркер супертипа (то есть то, чем является TypeToken, как он используется в Guice & Gson и других различных местах) в основном уловка, которая позволяет вам получить доступ к параметризованной информации о типе суперкласса через отражение. Также обратите внимание, что Javadoc говорит

Этот синтаксис нельзя использовать для создания литералов типа, которые имеют подстановочный знак параметры, такие как Class<?> или List<? extends> CharSequence>.

Это в основном ваша ситуация. Единственный выход, о котором я знаю, - это создание токена типа программно. Например, через Method.getGenericReturnType или глядя на то, как Guice использует токены типа, на первый взгляд у него есть более богатый набор служебных методов для выяснения этого. Пример того, как это сделать, можно найти в этом вопросе , в котором используются некоторые классы guice, но если вы посмотрите на источник guice, должно стать достаточно очевидным, что происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...