Это лучше, так как он принимает глобальные и локальные от вызывающего:
import sys
def execfile(filename, globals=None, locals=None):
if globals is None:
globals = sys._getframe(1).f_globals
if locals is None:
locals = sys._getframe(1).f_locals
with open(filename, "r") as fh:
exec(fh.read()+"\n", globals, locals)
Прежде всего, я не вижу, как это удобно для того, чтобы обернуть Gson.
Что касается вашей проблемы, то информация о самом родовом типе T
не доступна во время выполнения. Он был удален. Он доступен только во время компиляции. Вы хотите параметризовать его с фактическим типом, а не как new TypeToken<List<String>>
.
Из-за отсутствия повторных данных Generics в Java (невозможно выполнить T t = new T()
), сам Gson вынужден использовать подход TypeToken
, как вы видите. В противном случае Гссон сделал бы это более элегантно.
Чтобы иметь возможность передавать фактический тип вокруг, вы должны изобрести ту же самую вещь, что и TypeToken
. И это не имеет смысла :) Просто используйте его повторно или просто используйте Gson прямо, не упаковывая его в какой-то вспомогательный класс.
Я думаю, что первый ответ не указывает на фактическое решение: вы ДОЛЖНЫ также передать экземпляр класса вместе с T, например:
public T decode(String json, Class<T> cls) {
Gson gson = new Gson();
return gson.fromJson(json, cls);
}
Это потому, что здесь «T» - это тип ПЕРЕМЕННЫЙ , а не ссылку на тип; и используется только компилятором для добавления неявных бросков и проверки совместимости типов. Но если вы пройдете текущий класс, его можно использовать; и компилятор проверяет совместимость типов, чтобы уменьшить вероятность несоответствия.
В качестве альтернативы вы можете взять TypeToken и передать его; но TypeToken должен быть построен с реальным типом, а не с переменной типа; тип переменной здесь мало используется. Но если вы хотите обернуть вещи, вы не хотите, чтобы вызывающий абонент использовал TypeToken (который является типом Gson).
Тот же механизм обертывания будет работать с другими libs, такими как Jackson, которые вы упомянули.
Map<String, Object>.class
, только Map.class
. См. Также «справочное объяснение». ссылку в комментарии в моем ответе.
– BalusC
4 January 2011 в 19:45
Моим решением было использовать парсер json и разбить его на куски
public static <TT> PushObj<TT> fromJSON(String json, Class<TT> classType)
{
JsonObject jObj = new JsonParser().parse(json).getAsJsonObject();
String type = jObj.get("type").getAsString();
JsonObject job = jObj.get("object").getAsJsonObject();
TT obj = new Gson().fromJson(job, classType);
return new PushObj<TT>(type, obj);
}
. Если структура объекта: {String: Type, Generic: Object}
И переменными являются: jObj - это JSONObject строки, переданной внутри, а job - это объект JSONObject общего объекта
. Поэтому я использовал парсер json, чтобы получить тип отдельно, и отражение для объекта.
TypeToken
как аргумент класса или метода или, по крайней мере, изобрести его, если вы не хотите, чтобы в вашем API была обнаружена зависимость третьей стороны. Это открытый источник по лицензии Apache . Справочное объяснение здесь . – BalusC 19 November 2010 в 18:04