You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Java的toString方法自动输出JSON字符串?无需手动拼接

实现Java对象toString输出JSON的方案

方案一:统一基类+Jackson(优先推荐,全局配置)

写一个通用基类,重写toString方法用Jackson做序列化,所有需要的实体类直接继承这个基类即可,一次配置全复用。

步骤1:编写通用基类

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

public class BaseJsonEntity {
    // 全局统一配置序列化规则,按需调整
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .enable(SerializationFeature.INDENT_OUTPUT) // 可选:格式化JSON输出
            .disable(SerializationFeature.WRITE_NULL_MAP_VALUES); // 可选:忽略null字段

    @Override
    public String toString() {
        try {
            return OBJECT_MAPPER.writeValueAsString(this);
        } catch (Exception e) {
            // 序列化失败时用默认toString兜底,避免程序报错
            return super.toString();
        }
    }
}

步骤2:实体类继承基类

public class User extends BaseJsonEntity {
    private String userId;
    private String userName;

    // 常规getter、setter方法
    public String getUserId() { return userId; }
    public void setUserId(String userId) { this.userId = userId; }
    public String getUserName() { return userName; }
    public void setUserName(String userName) { this.userName = userName; }
}

使用效果

User user = new User();
user.setUserName("xxxxxxx");
System.out.print(user);
// 输出格式化后的JSON:
// {
//   "userName" : "xxxxxxx"
// }

这个方案的优势是全局统一管控,要调整序列化规则(比如日期格式、枚举处理),只需要修改基类里的ObjectMapper,所有子类自动生效,完全不用手写toString。


方案二:注解+字节码增强(无需继承,按需标注)

如果不想修改实体类的继承结构,可以用自定义注解+字节码增强的方式,给标记了注解的类动态生成JSON格式的toString方法。这里用ByteBuddy实现增强(需要引入ByteBuddy依赖)。

步骤1:自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 标记需要JSON格式toString的类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface JsonToString {
}

步骤2:实现字节码增强逻辑

import com.fasterxml.jackson.databind.ObjectMapper;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;

public class JsonToStringEnhancer {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .enable(SerializationFeature.INDENT_OUTPUT);

    // 程序启动时调用该方法安装增强器
    public static void install() {
        new ByteBuddy()
                .redefine(Object.class)
                .method(ElementMatchers.named("toString")
                        .and(ElementMatchers.returning(String.class)))
                .intercept(MethodDelegation.to(ToStringInterceptor.class))
                .make()
                .load(JsonToStringEnhancer.class.getClassLoader());
    }

    // 拦截toString调用的逻辑类
    public static class ToStringInterceptor {
        public static String intercept(Object obj) throws Exception {
            // 仅处理标记了@JsonToString的类
            if (obj.getClass().isAnnotationPresent(JsonToString.class)) {
                return OBJECT_MAPPER.writeValueAsString(obj);
            }
            // 未标记的类用默认toString
            return obj.getClass().getName() + "@" + Integer.toHexString(obj.hashCode());
        }
    }
}

步骤3:给实体类加注解

@JsonToString
public class User {
    private String userId;
    private String userName;

    // getter、setter省略
}

步骤4:启动时初始化增强器

在程序入口(比如main方法)第一行调用:

public class Main {
    public static void main(String[] args) {
        JsonToStringEnhancer.install();
        
        User user = new User();
        user.setUserName("xxxxxxx");
        System.out.print(user);
        // 输出JSON格式字符串
    }
}

这个方案不用改动类的继承关系,只需要给需要的类加注解,适合已有项目不想大范围调整类结构的场景。


补充说明

  • 两个方案都依赖Jackson核心包(com.fasterxml.jackson.core:jackson-databind),需要提前引入。
  • 统一配置时,Jackson的ObjectMapper支持各种序列化规则定制,比如日期格式、敏感字段过滤等,一次配置全类生效。
  • 字节码增强方案需要引入ByteBuddy依赖(net.bytebuddy:byte-buddy),如果是SpringBoot项目,也可以用Spring的BeanPostProcessor实现类似效果,但ByteBuddy更通用。

内容的提问来源于stack exchange,提问作者王先生

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:23:22