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

2021-04-07 14:47:42 +08:00
 yumc

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

5746 次点击
所在节点    Java
26 条回复
cubecube
2021-04-07 15:00:04 +08:00
Jooooooooo
2021-04-07 15:01:25 +08:00
这个在量大的时候影响性能.

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

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

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

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

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

正例:打印日志时,仅打印业务相关属性值或者调用其对象的 toString()方法。
binux
2021-04-08 00:55:32 +08:00
@xiaowangge 我不同意这个阿里规约,如果存在一个异常情况,现在不挂也是埋了一个定时炸弹。晚挂比如早挂,更多 code path 经过它,更早发现更好。
crclz
2021-04-08 01:35:22 +08:00
@binux 阿里规约指的是设计者主动抛出异常的情况吧。
xuanbg
2021-04-08 06:09:37 +08:00
@binux 实体类、vo 、dto 什么的可以直接用 JSON 工具将对象转换成 String 。其它类型基本上也不需要 toString()方法。
Michaelssss
2021-04-08 08:55:56 +08:00
toJson 本身会出错
watzds
2021-04-08 09:06:11 +08:00
没啥问题,绝大多数情况

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/768716

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX