JSON结构的 泛型和 **非泛型两种 Java 实体类实现方案
以下是针对该 JSON 结构的 泛型 和 非泛型 两种 Java 实体类实现方案,并分析它们的区别和适用场景:
方案 1:使用泛型(推荐)
特点:灵活复用,适合统一响应结构
import lombok.Data;
import java.time.OffsetDateTime;
import java.util.List;// 1. 基础响应泛型类
@Data
public class ApiResponse<T> {private Boolean success;private String code;private String message;private T result; // 泛型接收不同数据类型
}// 2. 分页结果泛型类
@Data
public class PageResult<T> {private List<T> records;private Integer total;private Integer size;private Integer current;private List<Object> orders;private Boolean optimizeCountSql;private Boolean hitCount;private Boolean searchCount;private Integer pages;
}// 3. 具体数据实体
@Data
public class ConferenceRoom {private Long conferenceId;private String conferenceName;private String conferenceNumber;private OffsetDateTime createDate;// 其他字段...
}// 使用示例
ApiResponse<PageResult<ConferenceRoom>> response = objectMapper.readValue(json, new TypeReference<ApiResponse<PageResult<ConferenceRoom>>>() {});
方案 2:非泛型(直接定义)
特点:直观简单,适合固定结构
import lombok.Data;
import java.time.OffsetDateTime;
import java.util.List;// 1. 完整响应实体(无泛型)
@Data
public class ConferenceApiResponse {private Boolean success;private String code;private String message;private ConferenceResult result;
}// 2. 分页结果实体
@Data
public class ConferenceResult {private List<ConferenceRoom> records;private Integer total;private Integer size;private Integer current;private List<Object> orders;private Boolean optimizeCountSql;private Boolean hitCount;private Boolean searchCount;private Integer pages;
}// 3. 会议室实体(同方案1)
@Data
public class ConferenceRoom {private Long conferenceId;private String conferenceName;// 其他字段...
}// 使用示例
ConferenceApiResponse response = objectMapper.readValue(json, ConferenceApiResponse.class);
核心区别对比
对比维度 | 泛型实现 | 非泛型实现 |
---|---|---|
代码复用性 | ✅ 一套结构适配所有接口 | ❌ 每套数据结构需单独定义类 |
可维护性 | 修改基类即可影响所有接口 | 需逐个修改相似结构的类 |
类型安全 | 编译时检查类型匹配 | 需手动保证字段一致性 |
JSON解析复杂度 | 需使用TypeReference 处理嵌套泛型 | 直接解析,无需处理泛型擦除 |
适用场景 | 多接口统一响应格式的系统 | 接口结构固定且简单的场景 |
扩展性 | 轻松支持新数据类型 | 新增数据类型需定义新类 |
如何选择?
-
选泛型 当:
- 项目有统一的响应格式标准(如
success/code/message/result
) - 需要处理多种数据类型(如分页的用户、订单、会议室等)
- 预期未来会新增大量相似结构的接口
- 项目有统一的响应格式标准(如
-
选非泛型 当:
- 接口结构完全固定且不会扩展
- 对泛型理解不深,追求简单实现
- 需要快速原型开发(减少泛型带来的初始复杂度)
注意事项
-
泛型的局限性:
- 运行时类型擦除:
List<ConferenceRoom>
在运行时变为List
,需通过TypeReference
保留类型信息
// 必须这样解析泛型 mapper.readValue(json, new TypeReference<ApiResponse<PageResult<ConferenceRoom>>>() {});
- 运行时类型擦除:
-
非泛型的冗余:
- 如果系统有20个分页接口,需要定义20个
XxxApiResponse
和XxxResult
类
- 如果系统有20个分页接口,需要定义20个
-
折中方案:
- 对少量特殊接口用非泛型,大部分统一接口用泛型