Gson # fromJson, как компилятор выводит параметр типа T? [Дубликат]

Во-первых, убедитесь, что в вашем каталоге python. Обычно он находится в C:\Python27. Если у вас другое, измените его из следующей команды.

Если после установки python все еще не распознается, в PowerShell введите это:

[Environment] :: SetEnvironmentVariable («Путь», «$ env: Путь; C: \ Python27», «Пользователь»)

Закройте PowerShell, а затем запустите его снова, чтобы убедиться, что Python теперь запущен. Если этого не произойдет, может потребоваться перезагрузка.

8
задан Thirumalai Parthasarathi 10 March 2014 в 08:13
поделиться

2 ответа

как метод выводит тип <T>

Это не так. Общие методы не вызывают их общие типы - вот почему T называется параметром типа . Вызывающий метод предоставляет аргумент типа для T. Когда это произойдет, может быть выведено компилятором на основе контекста аргументов вызова метода и целевого типа.

Например:

Set<String> c = Collections.emptySet();

emptySet объявляет параметр типа T, не принимает аргументов и возвращает Set<T>. Здесь компилятор сообщает T как String на основе целевого типа Set<String>.

Другой пример:

Collections.singleton("asdf");

singleton объявляет параметр типа T, принимает значение T и возвращает Set<T>. Здесь нет целевого типа, но компилятор сообщает T как String на основе аргумента "asdf".

Но типичный вывод типа - это просто удобство. Без него мы все равно могли бы использовать свидетелей типа типа для явного предоставления аргументов типа:

Set<String> c = Collections.<String>emptySet();
Collections.<String>singleton("asdf");

Это приводит нас к вашей сигнатуре метода:

public <T> void fromJsonArray(String jsonString, Type tToken)

fromJsonArray объявляет параметр типа T, но не возвращает ничего, связанного с типом T, или принимает аргументы, относящиеся к T. При вызове fromJsonArray компилятор не имеет информации, из которой следует вывести T. Его аргумент типа по умолчанию будет равен его верхней границе Object, если не используется тип свидетеля:

myObj.<String>fromJsonArray(jsonString, tToken);

Но это не имеет значения, поскольку <String> не влияет на поведение вызова метода или его компиляции. T бессмысленна * и может быть удалена из объявления fromJsonArray.

как компилятор присваивает значение, возвращаемое методом fromJson, переменная list, тип которой i не указана?

Вот источник Gson.fromJson(String, Type) :

@SuppressWarnings("unchecked")
public <T> T fromJson(String json, Type typeOfT) throws JsonParseException {
    StringReader reader = new StringReader(json);
    T target = (T) fromJson(reader, typeOfT);
    return target;
}

Вы может видеть, что он объявляет произвольный параметр типа T и отбрасывает десериализованный объект на T. Это известно как unchecked cast , потому что он не будет работать быстро, если это неправильно. Это потому, что T был удален во время выполнения. Вы можете видеть, что код подавляет предупреждение об этом, потому что это, как правило, плохая идея. Не ограничивая то, что T основано на аргументах метода, код Gson эффективно уступил контроль над ним вызывающему. Если вы написали:

List<String> list = g.fromJson(jsonString, tToken);

, но tToken представлены HashSet<String>, вы получите ClassCastException в этой строке во время выполнения. Хуже того, если tToken представлен ArrayList<Integer>, он даже не потерпит неудачу в этой строке, потому что JVM увидит только List и разрешит выполнение задания. A ClassCastException будет выпущен спустя некоторое время, как только ваш код попытается обработать элементы Integer в списке, такие как String s (и исключение будет путать с отладкой).

Итак, чтобы ответить на ваш вопрос о назначении компилятор позволяет присваивать результат fromJson всем, что угодно. Это зависит от вас, чтобы это было правильно.

Вы можете спросить: почему Gson делает непроверенный бросок и разрешает небезопасный код? Ответ заключается в том, что это удобство, связанное с языковыми ограничениями. Их другая подпись более безопасна:

public <T> T fromJson(String json, Class<T> classOfT)

Но нет способа представить общие типы с помощью Class - no List<String>.class, например. Только Type может это сделать, и он не является общим. fromJson может потребовать TypeToken<T>, но есть другие способы получить Type, поэтому это будет ограничительным.

Возврат Object и принуждение вызывающего к выполнению непроверенного акта были более прозрачными, но разработчики Gson, вероятно, хотели избежать этого «уродства».

10
ответ дан Community 22 August 2018 в 21:39
поделиться
  • 1
    Следуя далее следующему коду, я вижу, что typeOfT преобразуется в класс. Код находится в классе TypeUtils. – Ritesh 10 March 2014 в 03:45
  • 2
    @Ritesh Не могли бы вы увязать это? Я этого не вижу. – Paul Bellora 10 March 2014 в 03:56
  • 3
  • 4
    @Ritesh Извините, я просто пытаюсь понять, что вы имеете в виду под «Следуя далее коду». - Какова иерархия вызовов, связывающая toRawClass с fromJson? – Paul Bellora 10 March 2014 в 04:24
  • 5
    Я просто просмотрел (или щелкнул) через исходный код по ссылке, которую вы добавили, и нашел ссылку. Я не знаком с Gson, но в целом это кажется (из javadocs и из таких классов, как TypeToken, JsonDeserializationContext, JsonDeserializationVisitor, ParameterizedTypeHandlerMap и ParameterizedTypeImpl), что существует много кода для предоставления функции для любого параметризованного типа (кроме того, к простому случаю класса & lt; T & gt;), и это не относится к типу. Адаптеры нового типа можно зарегистрировать для настройки сериализации (см. Javadoc of com.google.gson.JsonSerializer). – Ritesh 10 March 2014 в 06:02
T list = g.fromJson(jsonString,tToken);

Он выводится из типа возврата g.fromJson().

3
ответ дан user207421 22 August 2018 в 21:39
поделиться
  • 1
    я попробовал, но это не тот случай, я думаю ... пожалуйста, посмотрите на мое редактирование .. спасибо за ответ .. :) – Thirumalai Parthasarathi 9 March 2014 в 15:31
  • 2
    Возвращаемый тип g.fromJson выведен из аргумента метода ttoken (Type) – Ritesh 9 March 2014 в 16:51
  • 3
    @Ritesh: я понимаю, что возвращаемый тип метода fromJson выводится из параметра типа, мне хотелось бы знать, как этот вывод помогает вывести тип T в моем методе – Thirumalai Parthasarathi 9 March 2014 в 18:33
  • 4
    Не уверен, что я понял. По определению общий метод использует параметры типа для выражения зависимостей между типами одного или нескольких аргументов и / или его возвращаемого типа. Если вы видите подписи fromJson, вы обнаружите, что использует параметр type, чтобы указать, что его аргумент (typeOfT) определяет тип возврата T. Ваш метод из JsonArray также является обобщенным методом - его вторым аргументом является typeOfT, и его подпись указывает этот тип возврата имеет тот же тип. – Ritesh 9 March 2014 в 18:56
  • 5
    Конечно, это так. Просто потому, что вы не могли получить свой собственный неправильный пример для компиляции, ничего не доказывает. Метод fromJson () выполняет . – user207421 10 March 2014 в 00:35
Другие вопросы по тегам:

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