как вывести тип при вызове статического универсального метода в Java [duplicate]

Это лучше, так как он принимает глобальные и локальные от вызывающего:

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)
21
задан BalusC 19 November 2010 в 17:43
поделиться

3 ответа

Прежде всего, я не вижу, как это удобно для того, чтобы обернуть Gson.

Что касается вашей проблемы, то информация о самом родовом типе T не доступна во время выполнения. Он был удален. Он доступен только во время компиляции. Вы хотите параметризовать его с фактическим типом, а не как new TypeToken<List<String>>.

Из-за отсутствия повторных данных Generics в Java (невозможно выполнить T t = new T()), сам Gson вынужден использовать подход TypeToken, как вы видите. В противном случае Гссон сделал бы это более элегантно.

Чтобы иметь возможность передавать фактический тип вокруг, вы должны изобрести ту же самую вещь, что и TypeToken. И это не имеет смысла :) Просто используйте его повторно или просто используйте Gson прямо, не упаковывая его в какой-то вспомогательный класс.

14
ответ дан BalusC 20 August 2018 в 18:13
поделиться
  • 1
    Я отменял фактическое использование GSON от механизма, который его использует. У меня есть интерфейс ObjectDecoder с расширением метода (String json). Это означает, что я могу переключаться между различными реализациями, например. GSON, Jackson и т. Д. Затем я использую Guice, чтобы ввести зависимость в механизм. – christophmccann 19 November 2010 в 18:03
  • 2
    Лучше всего на самом деле повторно использовать аргумент Gson TypeToken как аргумент класса или метода или, по крайней мере, изобрести его, если вы не хотите, чтобы в вашем API была обнаружена зависимость третьей стороны. Это открытый источник по лицензии Apache . Справочное объяснение здесь . – BalusC 19 November 2010 в 18:04

Я думаю, что первый ответ не указывает на фактическое решение: вы ДОЛЖНЫ также передать экземпляр класса вместе с 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, которые вы упомянули.

5
ответ дан StaxMan 20 August 2018 в 18:13
поделиться
  • 1
    Это не будет работать для параметризованных классов, в которых этот вопрос есть. Нет такой вещи, как Map<String, Object>.class, только Map.class. См. Также «справочное объяснение». ссылку в комментарии в моем ответе. – BalusC 4 January 2011 в 19:45
  • 2
    Да, я полностью осознаю эту проблему, просто вопрос не предполагает, что это был параметризованный класс, поэтому простой ответ казался достаточным. Жаль, что JDK не имеет эквивалента токена типа (ссылка на тип и т. Д., Каждый lib / framework должен определить свой собственный). – StaxMan 4 January 2011 в 19:49

Моим решением было использовать парсер 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, чтобы получить тип отдельно, и отражение для объекта.

0
ответ дан tommyz87 20 August 2018 в 18:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: