Подтвердить что ты не робот

По умолчанию конструктор no-args обязателен для Gson?

Руководство пользователя Gson утверждает, что мы должны определить конструктор по умолчанию no-args для любого класса, который будет работать с Gson правильно. Более того, в javadoc в классе Gson InstanceCreator сказано, что исключение будет выбрано, если мы попытаемся десериализовать экземпляр класса, отсутствующего конструктор по умолчанию, и мы должны использовать InstanceCreator в таких случаях. Тем не менее, я попытался проверить использование Gson с классом, не имеющим конструктора по умолчанию, и обе сериализации и десериализации работают без проблем.

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

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 без необходимости иметь конструктор по умолчанию или есть какие-то обстоятельства, когда он не будет работать?

4b9b3361

Ответ 1

Как и в случае с Gson 2.3.1.

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

Этот Unsafe класс обходит отсутствие конструктора no-args и имеет много других опасные виды использования. allocateInstance состояния

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

Таким образом, на самом деле он не нужен конструктор и обойдет ваш два конструктора аргументов. См. Примеры здесь.

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

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

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

Ответ 2

В Jackson есть хорошее решение:

fooobar.com/info/127679/...

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

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