以下是针对该 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个
-
折中方案:
- 对少量特殊接口用非泛型,大部分统一接口用泛型