If you have a container class, Jackson should deserialize to the type in the container class. I have renamed A to Animal and B to Bird.
public class Container {
public Animal animal;
public Container() {}
public static class Animal {
public Animal() {}
public Animal(int age) {
this.age = age;
}
public int age;
}
public static class Bird extends Animal {
public Bird() {}
public Bird(int age) {
super(age);
}
}
}
When serializing a Container object with a Bird and then deserializing it, it will become an Animal.
@Test
public void fromBirdToAnimal() throws IOException {
Container one = new Container();
one.animal = new Container.Bird(123);
String json = new ObjectMapper().writeValueAsString(one);
Container two = new ObjectMapper()
.readerFor(Container.class).readValue(json);
assertEquals(123, two.animal.age);
assertEquals(Container.Animal.class, two.animal.getClass());
}
If a container class is not possible but you know the class you need (the root class of your inheritance tree), telling ObjectMapper.readerFor
could help you out.
@Test
public void fromBirdToAnimal() throws IOException {
Container.Bird one = new Container.Bird(123);
String json = new ObjectMapper().writeValueAsString(one);
Container.Animal two = new ObjectMapper().readerFor(Container.Animal.class).readValue(json);
assertEquals(123, two.age);
assertEquals(Container.Animal.class, two.getClass());
}