Using Java inner classes for Jackson serialization

Pavel Polívka - Dec 15 '20 - - Dev Community

I recently picked up some work in progress done by a collegues not longer with a company. He wrote a lot of code, that probably never really compiled and my task was make sense of it and finish his work.
As part of making sense of it I made it compile. Next step was to run it.
Here I ran into ugly Jackson serialization exceptions.

Jist of the error massages was this.

can only instantiate non-static inner class by using default, no-argument constructor
Enter fullscreen mode Exit fullscreen mode

Strange I did not see any new classes without default constructor. I was digining in it for few seconds and figure out the source of my issues were inner classes added into some Dto classes.
These inner classes did not have any constructors but they still were source of my issues.

TL;DR

Just add static keyword to your inner class.

class ExampleClass {
    static class InnerClass {
        public int getCount() {
            return 42;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

How so?

Java has few types of inner classes. Anonymous, static and non-static inner classes.

The non static inner classes (including the anonymous ones) have set of hidden variables passed by hidden constructor, all done at compile time.
So if you have something like this

class ExampleClass {
    class InnerClass {
        public int getCount() {
            return 42;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Compiler will produce something like this

public class ExampleClass { ... }

class ExampleClass$InnerClass {
    private final ExampleClass parent;

    ExampleClass$InnerClass(ExampleClass p) {
        parent = p;
    }
    public int getCount() { 
        return 42; 
    }
}
Enter fullscreen mode Exit fullscreen mode

Why the hell is compiler doing something like this?
This is part of the magic why inner classes can access all members of enclosing class. Including the private ones.

Static inner classes are just normal classes without any abilities to read members of encosling classes. They do not have any hidden constructors, etc... That is why when you want to have inner class part of your Jackson serialiaziation it needs to be inner static class.

Jackson is refusing to work with non static classes as there is no easy way to instantiate those.


For more Java tips you can follow me on Twitter

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .