Недавно я взял в руки кое-какую незавершенную работу, выполняемую коллегами, которые больше не работают в компании. Он написал много кода, который, вероятно, никогда по-настоящему не компилировался, и моей задачей было разобраться в нем и закончить его работу. Чтобы разобраться в этом, я заставил его скомпилировать. Следующим шагом было запустить его. Здесь я столкнулся с уродливыми исключениями сериализации Джексона.
Суть сообщений об ошибках заключалась в следующем.
can only instantiate non-static inner class by using default, no-argument constructor
Странно, что я не видел никаких новых классов без конструктора по умолчанию. Я копался в этом несколько секунд и выяснил, что источником моих проблем были внутренние классы, добавленные в некоторые классы Dto. У этих внутренних классов не было никаких конструкторов, но они все еще были источником моих проблем.
TL;ДР
Просто добавьте статическое ключевое слово в свой внутренний класс.
class ExampleClass { static class InnerClass { public int getCount() { return 42; } } }
Как же так?
В Java есть несколько типов внутренних классов. Анонимные, статические и нестатические внутренние классы.
Нестатические внутренние классы (включая анонимные) имеют набор скрытых переменных, передаваемых скрытым конструктором, все это делается во время компиляции. Так если у вас есть что-то подобное
class ExampleClass { class InnerClass { public int getCount() { return 42; } } }
Компилятор создаст что-то вроде этого
public class ExampleClass { ... } class ExampleClass$InnerClass { private final ExampleClass parent; ExampleClass$InnerClass(ExampleClass p) { parent = p; } public int getCount() { return 42; } }
Какого черта компилятор делает что-то подобное? Это часть волшебства, почему внутренние классы могут получить доступ ко всем членам окружающего класса. В том числе и частные.
Статические внутренние классы – это просто обычные классы без каких-либо возможностей для чтения членов окружающих классов. У них нет никаких скрытых конструкторов и т.д… Вот почему, когда вы хотите, чтобы внутренний класс был частью вашей сериализации Джексона, он должен быть внутренним статическим классом.
Джексон отказывается работать с нестатическими классами, так как не существует простого способа их создания.
Для получения дополнительных советов по Java вы можете следовать за мной по Твиттер
Оригинал: “https://dev.to/pavel_polivka/using-java-inner-classes-for-jackson-serialization-4ef8”