kryo icon indicating copy to clipboard operation
kryo copied to clipboard

Add a @PostDeserialization annotation ?

Open jhoukem opened this issue 6 years ago • 3 comments

Hi Nate, would you consider a @PostDeserialisation annotation which would act like the @PostConstruct annotation for the EJB in Java EE ? For example I could have a class that need to execute some code only once after it has been deserialized:

public class Level {

    private transient int level
    private long xp;

    @PostDeserialization
    private void initialize() {
        level = ExperienceFormula.getLevelFromExperience(xp);
    }
}

In this scenario it would be handy to have a such annotation. Of course I could also write a custom serializer for my class that could take care of calling this initialization method but then I have to make its access public which is error prone (or use reflection which seems overkill).

jhoukem avatar Mar 13 '19 20:03 jhoukem

You can implement KryoSerializable / define a custom serializer as an inner static class and keep these fields private:

public class Level implements KryoSerializable {
    private /* transient */ int level;
    private long xp;

    @Override
    public void write (Kryo kryo, Output output) {
        output.writeVarLong(xp, true);
    }

    @Override
    public void read (Kryo kryo, Input input) {
        xp = input.readVarLong(true);
        level = ExperienceFormula.getLevelFromExperience(xp);
    }
}

// or

public class Level {
    private /* transient */ int level;
    private long xp;

    public static class LevelSerializer extends Serializer<Level> {
        @Override
        public void write (Kryo kryo, Output output, Level level) {
            output.writeVarLong(level.xp, true);
        }

        @Override
        public T read (Kryo kryo, Input input, Class<Level> type) {
            // Allows to use any constructor
            level.xp = input.readVarLong(true);

            Level level = new Level();
            level.level = ExperienceFormula.getLevelFromExperience(xp);
        }
    }
}

prineside avatar Nov 12 '20 20:11 prineside

Yes I know there is many workaround to achieve my goal however I would have prefer to have it be done automatically. Anyway thanks for your suggestions.

jhoukem avatar Nov 14 '20 09:11 jhoukem

Hmm... If I wanted to have this right now, I'd register a default serializer which extends the field serializer and calls super.read. After reading I'd check whether the object is instanceof PostDeserialization, with PostDeserialization being an interface containing a afterConstruction method or similar. That way, instead of an annotation you'd implement this interface and it would be called automatically after deserialization.

MarcMil avatar Mar 25 '21 13:03 MarcMil