content: package com.alibaba.fastjson2.issues_2500;
  
  import com.alibaba.fastjson2.JSON;
  import com.fasterxml.jackson.annotation.*;
  import com.fasterxml.jackson.core.JsonProcessingException;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import org.junit.jupiter.api.Test;
  
  import java.io.Serializable;
  import java.util.Objects;
  
  import static org.junit.jupiter.api.Assertions.assertEquals;
  
  public class Issue2548 {
      @Test
      public void fastJson() {
          CarDTO carDTO = new CarDTO();
          carDTO.setAge(10);
  
          String jsonString = JSON.toJSONString(carDTO);
          assertEquals("{\"vehicle_type\":\"Car\",\"age\":10}", jsonString);
  
          VehicleDTO vehicleDTO = JSON.parseObject(jsonString, VehicleDTO.class);
          assertEquals(vehicleDTO.getClass(), CarDTO.class);
          assertEquals("Car", vehicleDTO.getVehicleType());
      }
  
      @Test
      public void jackson() throws JsonProcessingException {
          ObjectMapper objectMapper = new ObjectMapper();
  
          CarDTO carDTO = new CarDTO();
          carDTO.setAge(10);
          String jsonString = objectMapper.writeValueAsString(carDTO);
          VehicleDTO vehicleDTO = objectMapper.readValue(jsonString, VehicleDTO.class);
          assertEquals(vehicleDTO.getClass(), CarDTO.class);
          assertEquals("Car", vehicleDTO.getVehicleType());
      }
  
      @JsonIgnoreProperties(
              value = "vehicle_type", // ignore manually set animal_type, it will be automatically generated by Jackson during serialization
              allowSetters = true // allows the animal_type to be set during deserialization
      )
      @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "vehicle_type", visible = true)
      @JsonSubTypes({
              @JsonSubTypes.Type(value = CarDTO.class, name = "Car"),
              @JsonSubTypes.Type(value = CycleDTO.class, name = "Cycle"),
      })
      public static class VehicleDTO
              implements Serializable {
          private static final long serialVersionUID = 1L;
  
          private String vehicleType;
  
          public VehicleDTO() {
              super();
          }
  
          /**
           * Constructor with only required parameters
           */
          public VehicleDTO(String vehicleType) {
              this.vehicleType = vehicleType;
          }
  
          public VehicleDTO vehicleType(String vehicleType) {
              this.vehicleType = vehicleType;
              return this;
          }
  
          /**
           * Get animalType
           *
           * @return animalType
           */
          @JsonProperty("vehicle_type")
          public String getVehicleType() {
              return vehicleType;
          }
  
          public void setVehicleType(String vehicleType) {
              this.vehicleType = vehicleType;
          }
  
          @Override
          public boolean equals(Object o) {
              if (this == o) {
                  return true;
              }
              if (o == null || getClass() != o.getClass()) {
                  return false;
              }
              VehicleDTO vehicle = (VehicleDTO) o;
              return Objects.equals(this.vehicleType, vehicle.vehicleType);
          }
  
          @Override
          public int hashCode() {
              return Objects.hash(vehicleType);
          }
  
          @Override
          public String toString() {
              StringBuilder sb = new StringBuilder();
              sb.append("class VehicleDTO {\n");
              sb.append("    vehicleType: ").append(toIndentedString(vehicleType)).append("\n");
              sb.append("}");
              return sb.toString();
          }
  
          /**
           * Convert the given object to string with each line indented by 4 spaces
           * (except the first line).
           */
          private String toIndentedString(Object o) {
              if (o == null) {
                  return "null";
              }
              return o.toString().replace("\n", "\n    ");
          }
      }
  
      @JsonTypeName("Car")
      public static class CarDTO
              extends VehicleDTO implements
              Serializable {
          private Integer age;
  
          public CarDTO() {
              super();
          }
  
          /**
           * Constructor with only required parameters
           */
          public CarDTO(String vehicleType) {
              super(vehicleType);
          }
  
          public CarDTO age(Integer age) {
              this.age = age;
              return this;
          }
  
          /**
           * Get age
           *
           * @return age
           */
  
          @JsonProperty("age")
          public Integer getAge() {
              return age;
          }
  
          public void setAge(Integer age) {
              this.age = age;
          }
  
          public CarDTO vehicleType(String vehicleType) {
              super.vehicleType(vehicleType);
              return this;
          }
  
          @Override
          public boolean equals(Object o) {
              if (this == o) {
                  return true;
              }
              if (o == null || getClass() != o.getClass()) {
                  return false;
              }
              CarDTO car = (CarDTO) o;
              return Objects.equals(this.age, car.age) &&
                      super.equals(o);
          }
  
          @Override
          public int hashCode() {
              return Objects.hash(age, super.hashCode());
          }
  
          @Override
          public String toString() {
              StringBuilder sb = new StringBuilder();
              sb.append("class CaDTO {\n");
              sb.append("    ").append(toIndentedString(super.toString())).append("\n");
              sb.append("    age: ").append(toIndentedString(age)).append("\n");
              sb.append("}");
              return sb.toString();
          }
  
          /**
           * Convert the given object to string with each line indented by 4 spaces
           * (except the first line).
           */
          private String toIndentedString(Object o) {
              if (o == null) {
                  return "null";
              }
              return o.toString().replace("\n", "\n    ");
          }
      }
  
      @JsonTypeName("Cycle")
      public static class CycleDTO
              extends VehicleDTO
              implements Serializable {
          public int id;
      }
  }
  