jackson version: 2.9.8 ```java package z.jack; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; public class Animal { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public static class Deserializer extends StdDeserializer { private final ObjectMapper mapper; public Deserializer() { super(Animal.class); this.mapper = new ObjectMapper(); } @Override public Animal deserialize(JsonParser p, DeserializationContext context) throws IOException { ObjectCodec codec = p.getCodec(); TreeNode treeNode = codec.readTree(p); if (treeNode.get("lives") == null) { return mapper.treeToValue(treeNode, Animal.class); } else { return codec.treeToValue(treeNode, Cat.class); } } } } //------- package z.jack; public class Cat extends Animal { private int lives; public int getLives() { return lives; } public void setLives(int lives) { this.lives = lives; } } //---------------- package z.jack; import java.util.List; public class Zoo { private List animals; public List getAnimals() { return animals; } public void setAnimals(List animals) { this.animals = animals; } } //---- test package z.jack; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.List; public class JacksonPolyTest { private ObjectMapper mapper; @Before public void setUp() { SimpleModule module = new SimpleModule(); module.addDeserializer(Animal.class, new Animal.Deserializer()); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(module); this.mapper = mapper; } @Test public void testJsonToParent() throws IOException { List animals = new ArrayList<>(); Animal a1 = new Animal(); a1.setName("what"); animals.add(a1); Zoo zoo = new Zoo(); zoo.setAnimals(animals); Writer w = new StringWriter(); mapper.writeValue(w, zoo); String json = w.toString(); System.out.println(json); Zoo deSerialized = mapper.readValue(json, Zoo.class); assert "what".equals(deSerialized.getAnimals().get(0).getName()); } @Test public void testJsonToChild() throws IOException { List animals = new ArrayList<>(); Cat cat = new Cat(); cat.setName("cat"); cat.setLives(9); animals.add(cat); Zoo zoo = new Zoo(); zoo.setAnimals(animals); String json = mapper.writeValueAsString(zoo); System.out.println(json); Zoo deSerialized = mapper.readValue(json, Zoo.class); assert "cat".equals(deSerialized.getAnimals().get(0).getName()); assert 9 == (((Cat) deSerialized.getAnimals().get(0)).getLives()); } } ```