
在使用 lombok 的 `@builder` 注解处理泛型类(如 `response
当为泛型类添加 @Builder 时,Lombok 会生成一个静态内部构建器类(如 ResponseBuilder<T>),其 builder() 方法本身是泛型静态方法:
public static <T> ResponseBuilder<T> builder() { ... }Java 编译器在调用 Response.builder() 时,默认将 <T> 推断为 Object(最宽上界),因此返回的是 ResponseBuilder<Object>,导致后续 .page(page)(传入 List<Article>)不兼容——因为 ResponseBuilder<Object>.page() 只接受 List<Object>。
✅ 正确写法:使用类型见证(Type Witness) 显式指定泛型参数:
long total = getTotalItemsCount();
List<Article> page = getPage();
Response<Article> response = Response.<Article>builder() // ← 关键:显式声明 T = Article
.status("ok")
.total(total)
.page(page)
.build();⚠️ 注意事项:
- 类型见证 <Article> 必须紧邻方法名(即 Response.<Article>builder()),不可写作 Response.builder<Article>()(语法错误);
- 若构建逻辑复杂,可考虑提取为局部变量增强可读性:
ResponseBuilder<Article> builder = Response.<Article>builder(); Response<Article> response = builder .status("ok") .total(total) .page(page) .build(); - 避免误用 @Builder 于含多个类型参数的类(如 Result<T, E>),此时类型见证更易出错;必要时可改用 @Builder(toBuilder = true) + 手动构造,或配合 @AllArgsConstructor(access = AccessLevel.PRIVATE) 自定义构建逻辑。
? 小结:这不是 Lombok 的限制,而是 Java 泛型类型推断的固有行为。只要理解 builder() 是一个泛型静态方法,就自然明白为何需要类型见证——它本质上是在“告诉编译器:这次我要的是 ResponseBuilder<Article>,不是默认的 ResponseBuilder<Object>”。









