Вопрос по default-constructor, gson, json, java – Является ли конструктор по умолчанию без аргументов обязательным для Gson?

50

Gson руководство пользователя заявляет, что мы должны определить конструктор по умолчанию без аргументов для любого класса для правильной работы с Gson. Еще больше, вJavadoc на ГсонаInstanceCreator класс сказал, что будет выдано исключение, если мы попытаемся десериализовать экземпляр класса, в котором отсутствует конструктор по умолчанию, и мыдолжен использованиеInstanceCreator в таких случаях. Однако я'Мы попытались протестировать использование Gson с классом, в котором отсутствует конструктор по умолчанию, и сериализация и десериализация работают без каких-либо проблем.

Вот кусок кода для десериализации. Класс без конструктора без аргументов:

public class Mushroom {
    private String name;
    private double diameter;

    public Mushroom(String name, double diameter) {
        this.name = name;
        this.diameter = diameter;
    }

    //equals(), hashCode(), etc.
}

и тест:

@Test
public void deserializeMushroom() {
    assertEquals(
            new Mushroom("Fly agaric", 4.0),
            new Gson().fromJson(
                    "{name:\"Fly agaric\", diameter:4.0}", Mushroom.class));
}

который отлично работает

Итак, мой вопрос:Могу ли я на самом деле использовать Gson без необходимости иметь конструктор по умолчанию или есть обстоятельства, когда он не будет работать?

Ваш Ответ

2   ответа
1

Есть хорошее решение вДжексон библиотека, как описано здесь:

https://stackoverflow.com/a/11838468/2854723

Дело в том, чтобы сообщить сериализатору черезФункция Mix-Ins какие поля JSON использовать при использовании конструктора с аргументами.

Если этот объект является частью внешней библиотеки, вы можетеудаленная аннотация " сСоздатель особенность.

82

Начиная с Gson 2.3.1.

Независимо от того, что говорится в документации Gson, если ваш класс неу вас нет конструктора без аргументов и вы еще не зарегистрировалиInstanceCreater объекты, то это создастObjectConstructor (который создает ваш объект) сUnsafeAllocator который использует Reflection, чтобы получитьallocateInstance метод классаsun.misc.Unsafe создать свой класс " пример.

этоUnsafe учебный класс обходит отсутствие конструктора без аргументов и имеетмного других опасных применений.allocateInstance состояния

Выделите экземпляр, но не запускайте конструктор. Инициализирует класс, если он еще не был.

Так что это нена самом деле нужен конструктор, и он будет обходить ваш конструктор с двумя аргументами. Смотрите несколько примеровВот.

Если у вас есть конструктор без аргументов, Gson будет использоватьObjectConstructor который использует этот по умолчаниюConstructor позвонив по телефону

yourClassType.getDeclaredConstructor(); // ie. empty, no-args

Мои 2 цента: Следуйте указаниям Gson и создайте свои классы с помощью конструктора без аргументов или зарегистрируйтеInstanceCreator, Вы можете оказаться в плохом положении, используя.Unsafe

@ thomas.mc.work Gson сможет установить поле непосредственно с помощью отражения (и, возможно, какой-нибудь небезопасной работы), и вы сможете получить его через геттер (или напрямую через поле.Я не рекомендую этот дизайн. Sotirios Delimanolis
мы нашли хорошее решение дляfinal Проблема с библиотекой Джексона, которая описана здесь:stackoverflow.com/a/11838468/2854723 thomas.mc.work
Что, если у меня есть конструктор по умолчанию, который устанавливает мой последний элемент в null, но для этого элемента нет установщика? Это разумное решение? thomas.mc.work
В соответствии сhttps://sites.google.com/site/gson/gson-user-guide#TOC-Using-Gson Вы можете использовать частный конструктор, который предотвратит использование небезопасных. Из того, что япроверил, когда яМы использовали приватный конструктор GSON использовал следующий метод: com.google.gson.internal.newDefaultConstructor Когда я удалил приватный конструктор, GSON использовал следующий метод: com.google.gson.internal.newUnsafeAllocator Tzach Solomon

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