Если вы запустите javap -p User.class
, вы получите следующий вывод:
public final class q54491286.User {
private final java.lang.String name;
private final int age;
public final java.lang.String getName();
public final int getAge();
public q54491286.User();
}
Неизменность Kotlin поддерживается никакими методами-мутаторами, сгенерированными для полей, которые (неявно) объявлены private
и final
.Если вы не определили адаптер пользовательского типа, Gson по своему дизайну не использует ни аксессоры, ни мутаторы во время сериализации и десериализации соответственно по проекту для классов объектов простых данных (подробнее здесь в Использование полей против геттеров для обозначения элементов Json раздел).Кроме того, Gson может модифицировать final
поля, и это тоже выбор дизайна.
Из-за интенсивного использования отражения неизменяемость - довольно относительная вещь в Java.Например, я могу легко изменить неизменяемую (по замыслу) строку, используя отражение, делая ее своего рода изменяемой ( намерения ):
final String s = "foo";
final Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
valueField.set(s, new char[]{ 'b', 'a', 'r' });
System.out.println(s);
Это приводит к bar
при использовании моегоjava
от java version "1.8.0_191"
.Нет неизменности, хе-хе.
С другой стороны, если ваш класс может быть обнаружен методом переопределения стратегий адаптеров типа Gson универсальным способом (Gson запрещает переопределять адаптеры типа Object
и JsonElement
), вы сможете написать собственный десериализатор, который запрещает сгенерированным Kotlin классам (обнаруженным аннотацией kotlin.Metadata
) иметь десериализованные поля только для чтения (хотя и не уверен, что он имеет преимущество).Или просто внедрите десериализатор, который будет сканировать поток / дерево JSON на предмет полей, не предназначенных только для чтения, и использовать их только при создании нового объекта User
с его легальным конструктором, не использующим отражение.
Iне знаю, является ли это «особенностью» Gson или «ошибкой».
Подводя итог, это особенность.
Итак, мой вопрос:Можем ли мы полагаться на это, или это поведение может измениться позже?
Это, скорее всего, никогда не изменится в Gson 2.x.Насколько я знаю, никаких планов по выпуску серьезного обновления, Gson 3.x и т. Д. Нет.