Java 数据对象的 toString()重写为 Json 格式的优劣 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yumc
V2EX    Java

Java 数据对象的 toString()重写为 Json 格式的优劣

  •  
  •   yumc 2021-04-07 14:47:42 +08:00 6225 次点击
    这是一个创建于 1649 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题 我认为在打印日志场景下,直接使用数据对象的 toString()输出 Json 格式文本非常方便,但是并没有在开发中发现有大规模这种用法,都有哪些不足呢

    26 条回复    2021-04-09 09:22:42 +08:00
    cubecube
        1
    cubecube  
       2021-04-07 15:00:04 +08:00
    Jooooooooo
        2
    Jooooooooo  
       2021-04-07 15:01:25 +08:00
    这个在量大的时候影响性能.

    如果日志不是异步的还可能卡住业务线程, 弄成了异步了依然有可能对 cpu 造成可见压力.

    方便归方便, 打的时候还是注意下不要太大.
    zhilincom
        3
    zhilincom  
       2021-04-07 15:44:31 +08:00 via Android
    @Jooooooooo 硬编码直接以字符串拼接的方式生成 Json 的话应该不会很慢吧?就像用 IDEA 的 generate 生成的 toString()方法那样。或者像 Lambok 那样在编译时生成。
    timethinker
        4
    timethinker  
       2021-04-07 15:50:35 +08:00
    @zhilincom 硬编码拼接除非字符串这些是固定可预期的值,否则会出现像 SQL 注入的那样,破坏了 JSON 的结构。另外,反过来想,与其调用 toString 返回 JSON 字符串,为什么不直接把对象传给 JSON 序列化器呢?

    例如:JSON.stringify(obj)
    chendy
        5
    chendy  
       2021-04-07 15:53:08 +08:00
    首先,java 本身没有 json 相关功能,需要依赖第三方库
    其次,简单对象普通的 toString 就可以看得很明白了
    最后,复杂对象用 json 格式然后复制粘贴格式化确实方便一些,特定场景特殊处理即可,不需要全部用
    Jooooooooo
        6
    Jooooooooo  
       2021-04-07 16:01:00 +08:00
    @zhilincom 那个也有性能损耗的, 只是肯定比 JSON 快. 大了都有问题, 日志不要太大.
    est
        7
    est  
       2021-04-07 16:04:00 +08:00
    JSON 的概括能力有限。
    lidlesseye11
        8
    lidlesseye11  
       2021-04-07 16:12:26 +08:00
    可能是因为 toString 方法不只是为了打日志?
    我倒觉得日志里用 json 不是也挺正常吗。。不用 json 的各位都是用的什么格式啊?
    wakzz
        9
    wakzz  
       2021-04-07 16:37:28 +08:00
    JSON 序列化的 CPU 消耗还是很可观的,就如二楼所述,调用频率高真的会吃很高的 CPU
    xy2401
        10
    xy2401  
       2021-04-07 19:14:18 +08:00
    如果你手动拼接 json 不用工具。。。应该没有任何问题。。。。tostring 爱吐啥吐啥
    Anarchy
        11
    Anarchy  
       2021-04-07 19:30:23 +08:00
    把 JSON 这类序列化的能力和简单对象做分离吧,没必要合在一起。如果放在 toString 里,首先不能考虑人为编码的方式修改吧(太容易出错)。只能选工具生成或者把 ORM 类库的调用写在里面,另外 toString 改成 toJSON 就把含义变小了,可能还要搞个接口代表这些实体的 toString 是 toJSON 。感觉就是没必要
    guyeu
        12
    guyeu  
       2021-04-07 20:17:50 +08:00
    1. JSON 格式没办法良好表达很多数据结构(比如二维数组、循环链表)和一些面向对象概念(继承,多态);
    2. 代码生成一个无性能损失的 toJsonString 很难;
    TmacV2
        13
    TmacV2  
       2021-04-07 20:57:33 +08:00 via iPhone
    你们都这么考虑性能吗
    xuanbg
        14
    xuanbg  
       2021-04-08 00:29:33 +08:00
    什么性能问题,说的和真的似的。。。对象序列化成 Json 字符串都能影响到性能了,这日志怕是分分钟就要把存储空间给打爆!!!还是多操心一些日志该不该打的问题,然后再来考虑打日志的性能问题吧。
    xiaowangge
        15
    xiaowangge  
       2021-04-08 00:44:51 +08:00 via iPhone
    阿里规约:

    [强制] 打印日志时,禁止直接用 JSON 工具将对象转换成 String 。

    说明:如果对象里某些 get 方法被覆写,存在抛出异常的情况,则可能会因为打印日志而影响正常的业务流程的执行。

    正例:打印日志时,仅打印业务相关属性值或者调用其对象的 toString()方法。
    binux
        16
    binux  
       2021-04-08 00:55:32 +08:00 via Android
    @xiaowangge 我不同意这个阿里规约,如果存在一个异常情况,现在不挂也是埋了一个定时炸弹。晚挂比如早挂,更多 code path 经过它,更早发现更好。
    crclz
        17
    crclz  
       2021-04-08 01:35:22 +08:00
    @binux 阿里规约指的是设计者主动抛出异常的情况吧。
    xuanbg
        18
    xuanbg  
       2021-04-08 06:09:37 +08:00
    @binux 实体类、vo 、dto 什么的可以直接用 JSON 工具将对象转换成 String 。其它类型基本上也不需要 toString()方法。
    Michaelssss
        19
    Michaelssss  
       2021-04-08 08:55:56 +08:00
    toJson 本身会出错
    watzds
        20
    watzds  
       2021-04-08 09:06:11 +08:00 via Android
    没啥问题,绝大多数情况
    timi
        21
    timi  
       2021-04-08 09:06:59 +08:00
    IDEA 可以定制 toString 模板,生成类似 json 风格的串:
    https://blog.csdn.net/wenqiangluyao/article/details/109183224
    securityCoding
        22
    securityCoding  
       2021-04-08 10:08:07 +08:00
    @timi +1,直接模版生成拼接好就行了
    yazinnnn
        23
    yazinnnn  
       2021-04-08 11:42:25 +08:00
    public class GenericJson extends GenericData implements Cloneable {
    .....
    @Override
    public String toString() {
    if (jsonFactory != null) {
    try {
    return jsonFactory.toString(this);
    } catch (IOException e) {
    throw Throwables.propagate(e);
    }
    }
    return super.toString();
    }
    .....
    }

    google 的 sdk 里直接重写了 toString...
    当然这是业务 api 才重写,并不是所有类....
    aguesuka
        24
    aguesuka  
       2021-04-08 12:14:40 +08:00 via Android
    性能什么的都是假的。
    因为重写父类的方法付出的维护成本和心智负担远不止代码的工作量,没有足够回报就不要去动。
    pancl
        25
    pancl  
       2021-04-08 19:35:00 +08:00 via Android
    idea 生成重写方法生成 json 就是字符串拼接的
    ychost
        26
    ychost  
       2021-04-09 09:22:42 +08:00
    基本都是通过 @ToString 来打印的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     926 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 22:50 PVG 06:50 LAX 15:50 JFK 18:50
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86