V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yumc
V2EX  ›  Java

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

  •  
  •   yumc · 7 天前 · 2605 次点击

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

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

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

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

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

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

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

    正例:打印日志时,仅打印业务相关属性值或者调用其对象的 toString()方法。
    binux
        16
    binux   6 天前 via Android
    @xiaowangge 我不同意这个阿里规约,如果存在一个异常情况,现在不挂也是埋了一个定时炸弹。晚挂比如早挂,更多 code path 经过它,更早发现更好。
    crclz
        17
    crclz   6 天前
    @binux 阿里规约指的是设计者主动抛出异常的情况吧。
    xuanbg
        18
    xuanbg   6 天前
    @binux 实体类、vo 、dto 什么的可以直接用 JSON 工具将对象转换成 String 。其它类型基本上也不需要 toString()方法。
    Michaelssss
        19
    Michaelssss   6 天前
    toJson 本身会出错
    watzds
        20
    watzds   6 天前 via Android
    没啥问题,绝大多数情况
    timi
        21
    timi   6 天前
    IDEA 可以定制 toString 模板,生成类似 json 风格的串:
    https://blog.csdn.net/wenqiangluyao/article/details/109183224
    securityCoding
        22
    securityCoding   6 天前
    @timi +1,直接模版生成拼接好就行了
    yazinnnn
        23
    yazinnnn   6 天前
    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   6 天前 via Android
    性能什么的都是假的。
    因为重写父类的方法付出的维护成本和心智负担远不止代码的工作量,没有足够回报就不要去动。
    pancl
        25
    pancl   6 天前 via Android
    idea 生成重写方法生成 json 就是字符串拼接的🌝
    ychost
        26
    ychost   5 天前
    基本都是通过 @ToString 来打印的
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1962 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 17ms · UTC 16:10 · PVG 00:10 · LAX 09:10 · JFK 12:10
    ♥ Do have faith in what you're doing.