如何修改Lombok @ToString注解生成的toString方法输出格式?
调整Lombok @ToString生成的输出格式
你说得对,默认情况下Lombok的@ToString(包括@Data注解里集成的)生成的输出确实比较紧凑,遇到嵌套的Map、List这类复杂结构时可读性会大打折扣。比如你给出的简单示例:
@Data class Test { int a; int b; } Test test = new Test(1, 2); System.out.println(test.toString());
默认输出通常是:
Test(a=1, b=2)
如果是包含嵌套集合的复杂类,输出会挤成一团,非常难读。不过完全可以通过配置或自定义来优化格式,下面分享几种实用方案:
1. 利用Lombok自带配置快速调整格式
Lombok的@ToString注解提供了不少参数,能直接调整输出样式,最常用的是指定style参数来匹配不同的格式化风格:
示例:多行格式化输出
如果希望每个字段单独占一行,可读性更强,可以使用ToStringStyle.MULTI_LINE_STYLE(需要依赖Apache Commons Lang3,大部分Java项目都已引入):
import lombok.Data; import lombok.ToString; import org.apache.commons.lang3.builder.ToStringStyle; @Data @ToString(style = ToStringStyle.MULTI_LINE_STYLE) class Test { int a; int b; List<String> items; Map<String, Integer> map; } // 输出示例: Test@1b6d3586[ a=1 b=2 items=[apple, banana] map={key1=10, key2=20} ]
其他常用配置项
includeFieldNames = false:去掉字段名,只输出值(适合极简场景)callSuper = true:如果类继承了父类,会包含父类的字段内容exclude = {"fieldName"}:排除不需要输出的敏感或冗余字段
2. 手动编写toString()完全自定义格式
如果Lombok的默认配置满足不了你的个性化需求,直接手动实现toString()方法是最灵活的方式,比如针对嵌套结构做缩进或特殊格式化:
import lombok.Data; import java.util.List; import java.util.Map; @Data class Test { int a; int b; List<String> items; Map<String, Integer> map; @Override public String toString() { StringBuilder sb = new StringBuilder("Test{\n"); sb.append(" a=").append(a).append(",\n"); sb.append(" b=").append(b).append(",\n"); sb.append(" items=").append(items).append(",\n"); sb.append(" map=").append(map).append("\n"); sb.append("}"); return sb.toString(); } } // 输出示例: Test{ a=1, b=2, items=[apple, banana], map={key1=10, key2=20} }
3. 用@ToString的doWith参数做高级定制
如果需要对特定字段做特殊处理(比如格式化日期、加密敏感数据、自定义集合输出),可以通过doWith参数传入自定义的ToStringCall实现,精细控制每个字段的输出逻辑:
import lombok.Data; import lombok.ToString; import lombok.ToString.ToStringCall; import java.util.List; import java.util.Map; @Data @ToString(doWith = CustomToStringHandler.class) class Test { int a; int b; List<String> items; Map<String, Integer> map; public static class CustomToStringHandler implements ToStringCall<Test> { @Override public String call(Test instance) { StringBuilder sb = new StringBuilder("Test("); sb.append("a=").append(instance.getA()); sb.append(", b=").append(instance.getB()); // 对List做自定义分隔符格式化 sb.append(", items=["); sb.append(String.join(" | ", instance.getItems())); sb.append("]"); // 对Map做键值对的自定义格式化 sb.append(", map={"); instance.getMap().forEach((k, v) -> sb.append(k).append(":").append(v).append(", ")); if (!instance.getMap().isEmpty()) { sb.delete(sb.length() - 2, sb.length()); // 移除最后多余的逗号空格 } sb.append("})"); return sb.toString(); } } } // 输出示例: Test(a=1, b=2, items=[apple | banana], map={key1:10, key2:20})
这些方案可以根据你的实际需求灵活选择,不管是简单类还是复杂嵌套结构,都能生成清晰易读的toString()输出!
内容的提问来源于stack exchange,提问作者jaeyong
相关产品推荐
相关产品推荐

