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

Java model 对象必须实现 Serializable 吗?

  •  
  •   sawyera · 2020-09-29 20:40:36 +08:00 · 5622 次点击
    这是一个创建于 1276 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    我实习生。

    今天( 2020-09-29 ),组长 review 我的代码时发现我 model 中的对象都没有实现 Serializable 接口,告诉我:”写得不对,所有有关落库、网络传输的对象都必须实现 Serializable 接口“。我不以为然,我印象中此接口是需要逐渐被废弃使用的,并且只有使用 Java 原生的序列化机制时才需要此接口。

    我检查代码后还是觉得没必要实现 Serialzable 接口,原因:

    1. rpc 业务层面使用 fastjson 编解码 json String

    2. mybatis 的操作与 Serialzable 接口无关

    3. 业务层面前端入参和出参的 vo 也是 fastjson 编解码 json String

    4. 查了资料复习此接口的使用,发现和我印象中的理解偏差不大

    以上,我认为此项目 model 中的对象不需要实现 Serializable 接口。

    随后和组长、一些同事讨论了下,他们一致认为必须实现 Serialzable 接口,理由:

    1. 有序列化的地方必须实现

    2. 落库的对象必须实现

    3. rpc 传输的对象必须实现

    4. 老的代码都实现了 Serialzable 接口,没有人是不这么做的,别想偷懒

    5. 老的项目中不实现 Serialzable 接口,然后踩坑了

    我用我的原因进行反驳,同事的口径大致是:”如果我有能力承担不实现 Serialzable 接口带来的后果,那就不实现“。

    后续

    我老老实实地把 model 中的对象都加上了 Serialzable 接口。

    后续怎么想怎么不对,我感觉自己的想法没错,我只是想把代码写得干净一点,想来问问大家对此接口的看法。

    问题

    1. Java model 对象必须实现 Serializable 吗?想知道大家都此接口的理解

    2. 如果我的想法没错,那么同事对 Serializable 接口的理解是否反映某些问题?

    一些参考: https://v2ex.com/t/696834

    43 条回复    2020-10-03 07:01:46 +08:00
    mightofcode
        1
    mightofcode  
       2020-09-29 20:51:49 +08:00
    不一定
    java 自己内嵌了很多机制,比如 Serializable,Serializable 不是必须的,没有 Serializable 你也一样写程序,甚至比 Serializable 做的更好

    Serializable 不好用,java 自带的序列化也做的不行,这两个都建议别用了
    mightofcode
        2
    mightofcode  
       2020-09-29 20:54:04 +08:00
    你们应该有测试吧
    业务能跑就说明没问题

    你的同事有点僵硬
    zsdroid
        3
    zsdroid  
       2020-09-29 20:55:20 +08:00
    所以坑呢?
    chenshun00
        4
    chenshun00  
       2020-09-29 21:02:13 +08:00   ❤️ 1
    我寻思着 Serializable 接口也没被标明 @Deprecated 啊,你印象中的「此接口是需要逐渐废弃使用的」是如何得来的. :)

    难道你们的 RPC 都走的是字符串. :)
    sawyera
        5
    sawyera  
    OP
       2020-09-29 21:02:46 +08:00
    @mightofcode 我也认为测试业务能跑就说明没问题,但是同事用一个奇葩的理由反驳我:”一百次成功也说明不了问题,不实现 Serializable 的话,可能下次调用就失败了,到时候吐空数据给前端你能承担后果吗?“


    @zsdroid 我让同事复现坑,同事复现不出来,说”之前好像使用 jackson 序列化不实现 Serialzable 的类会报错“,然后就别人的代码都这么写你也要这么写、承担后果之类的话
    oneisall8955
        6
    oneisall8955  
       2020-09-29 21:08:16 +08:00 via Android
    学习这个接口的时候,Demo 是序列化到磁盘,课本中说还有一个作用是网络传输。很疑惑的是现在接口间都是 json 作为介质了吧。另外缓存到 redis 默认情况也是转 json 字符串到内存 value 的。
    现在就职的公司代码生成器生成代码是实现了这个接口,我每次生成新代码都删掉了,觉得很碍地方。。。
    以前公司也没见用
    idoggy
        7
    idoggy  
       2020-09-29 21:11:03 +08:00 via Android
    落库的对象要序列化,这系统至少六年朝上了吧
    billlee
        8
    billlee  
       2020-09-29 21:16:00 +08:00
    需要考虑性能的地方都不用。Json/kryo/protobuf 哪个不比 serializable 好用
    huifer
        9
    huifer  
       2020-09-29 21:17:50 +08:00
    如果需要使用 ObjectOutputStream ObjectInputStream 那么必须实现. 如果说落入 DB , 这可以不需要. mybatis jpa 应该没有强制要求. 如果是 fastjson 或者其他 json 序列化通过这类工具反序列化和序列化都没有强制要求实现 Serializable 接口. redis 这类都提供了序列化方式的重写接口,通过这些重写可以替换掉原有的,即可以转换为 fastjson 等序列化工具.
    ssynhtn
        10
    ssynhtn  
       2020-09-29 21:18:17 +08:00 via Android
    你的同事水平有点低啊
    sawyera
        11
    sawyera  
    OP
       2020-09-29 21:19:10 +08:00
    @chenshun00 「此接口是需要逐渐废弃使用的」相关文章: https://adtmag.com/articles/2018/05/30/java-serialization.aspx 和之前学习的差不多。RPC 走 String 序列化后的 byte[],但是 RPC 的序列化机制也不至于使用 Java 自带的机制吧,并且就算使用了那也是序列化 String,和 model 中的类无关。


    @oneisall8955 和你对 Serialzable 同样的理解,看到代码中的 Serialzable,也恨不得一个个删掉


    @idoggy 新项目,Java 后端 ssm 那一套,我想着也用不到 Serialzable 啊
    smilekung
        12
    smilekung  
       2020-09-29 21:23:57 +08:00
    dubbo 的默认序列化应该是要实现的,刚工作的时候也经常忘
    lxk11153
        13
    lxk11153  
       2020-09-29 22:07:28 +08:00
    @smilekung #12 [233]换 serialization 就行了
    @sawyera 不需要 [doge], 不要纠结这个,领导说写就写,反正又不麻烦,不管警告的话直接 parent 类实现下就行
    youxiachai
        14
    youxiachai  
       2020-09-29 22:45:24 +08:00
    万一要对接一个很老的序列化接口,不就能用上了..[doge]
    BBCCBB
        15
    BBCCBB  
       2020-09-29 23:01:36 +08:00
    这个接口的确是有废弃的迹象. 也没啥用, 不用实现.
    night98
        16
    night98  
       2020-09-29 23:03:23 +08:00
    有部分客户端在传输的时候需要这个东西,不过我个人是觉得加不加无所谓,真有问题了再加也不迟
    nvkou
        17
    nvkou  
       2020-09-29 23:05:47 +08:00 via Android   ❤️ 1
    把这个问题抽象一下就是:上头要我写屎山还不接受反驳?
    这个问题的答案是:如果你只是拧螺丝的就别怪图纸,有意见等自己也出图纸的时候。

    在公司角度来看,工作人员是流动的,但生产事故是公司的。权责不统一的情况下听责任方
    hhhsuan
        18
    hhhsuan  
       2020-09-29 23:12:18 +08:00 via Android
    让你写就写,别那么多废话,你吵了半天能给你加工资吗
    Saurichthys
        19
    Saurichthys  
       2020-09-29 23:37:42 +08:00 via iPhone
    定义一个 basemodel 实现序列化,业务对象继承就好了,哪来事这么多需要每个都写一遍!?
    wangyanrui
        20
    wangyanrui  
       2020-09-30 00:03:47 +08:00 via Android
    领导让写就写,除非你能推动大家都不写
    sagaxu
        21
    sagaxu  
       2020-09-30 00:44:39 +08:00 via Android   ❤️ 1
    祖传代码把 model 不加检查 cast 成 Serializable,抛异常了你去抓吗?

    老项目就别作死了,宁可复制粘贴搞臭一点,也要保持队形
    lidlesseye11
        22
    lidlesseye11  
       2020-09-30 01:01:33 +08:00
    不用实现,以后真要用到了再加。这种东西行就是行,不行就是不行,哪有“可能下次调用就失败了”的情况。。。
    但也不用纠结,说两句说不过乖乖加上就算了。。如果大家都加那至少看起来整齐(狗头
    kuangwinnie
        23
    kuangwinnie  
       2020-09-30 04:17:22 +08:00
    听领导的,他承担责任
    diegozhu
        24
    diegozhu  
       2020-09-30 08:41:38 +08:00
    同事属于保守派。
    写代码自己不是老大的话,还是不要特立独行的好,跟群众走总是没错的。

    现在测试能通过,只能代表当前这个代码,状态,结构能通过。保不准后面换个什么 orm,json 的框架,就尿崩了。
    更保不准后面会引入什么框架需要。

    要么你说服所有人,让他们都去掉或者你全部都去掉,要么你自己加,代码风格不一致以后会有很多坑。
    simonlu9
        25
    simonlu9  
       2020-09-30 09:02:33 +08:00
    Serializable 忘记加 uid 是个大坑,建议慎用
    hand515
        26
    hand515  
       2020-09-30 09:17:12 +08:00
    新项目能不用就不用
    shm7
        27
    shm7  
       2020-09-30 09:17:42 +08:00 via iPhone
    7 楼 18 楼 都是精明人
    monkeyWie
        28
    monkeyWie  
       2020-09-30 09:37:19 +08:00
    可以不写但是没必要🐶
    passerbytiny
        29
    passerbytiny  
       2020-09-30 10:21:24 +08:00 via Android   ❤️ 2
    一些(可能还是决大多数) RPC 框架,都需要 Serializable,如果不是独立项目,说必定哪天就可能要加 RPC,那时候规范化的 Serializable 可能会将成本降低 1 %:Serializable 虽是鸡肋但不能弃。

    维护现有规范,比制定新规范更容易。

    以上两点决定了你的组长是对的。但是,以上两点决定了你的组长已经到上限了,你跟着他是没有前途的。
    zoharSoul
        30
    zoharSoul  
       2020-09-30 10:27:29 +08:00
    让你写就写,别那么多废话,你吵了半天能给你加工资吗

    犯不着纠结这种细枝末节.加就完事了.
    watcher
        31
    watcher  
       2020-09-30 10:32:21 +08:00   ❤️ 1
    大兄得,搞工程 没听过哪个砌墙抹灰的家伙敢放话说这面墙是多余的我不砌了...
    no1xsyzy
        32
    no1xsyzy  
       2020-09-30 10:35:36 +08:00
    寓言故事:猴子定律 或者 湿猴理论

    顺便一提,作为没写过 Java 但成天听说 Java 反序列化出高危漏洞,觉得不实现比较安全。
    passerbytiny
        33
    passerbytiny  
       2020-09-30 10:55:44 +08:00 via Android
    楼主和楼上的人有一些误区:

    一、JSON 不是序列化。Java 对象与 Json 字符串之间不是一一对应而是多对一关系,JSON 只能做序列不能做反序列。加一些特殊标记可以将关系搞成一一对应,但那已经不是 JSON 了。Java 就算去掉现有的 Serializable,也是用二进制格式或者新建格式,新建格式可能会与 JSON 有关,但绝对不会是 JSON 。

    二、虽然大多 RPC 用 JSON,但是基于 Java 序列化的 RPC 框架还活着并且活得不算差。

    三、楼上有人已经提过了,Serializable 还没被标记为 Deprecated 。
    codingbody
        34
    codingbody  
       2020-09-30 13:40:38 +08:00   ❤️ 1
    #### 五只猴子的故事

    > 科学家在笼子里放了五只猴子。笼子中间有一架梯子,梯子上面放着香蕉。

    每当一只猴子爬上梯子,科学家就用冷水泼洒其余的猴子。过了一阵子,只要一只猴子爬上梯子,其他猴子就会殴打它。一段时间后,所有猴子都不敢爬上梯子。

    然后,科学家用一只新猴子,替换了原来的一只猴子,并且停止用冷水泼洒猴子。这只新猴子立即爬楼梯去拿香蕉,但随即遭到其他猴子的殴打。经过几次殴打,新猴子学会了不爬梯子,即使它从来不知道为什么。

    接着,替换了第二只猴子,也发生了同样的事情。刚才放进笼子的那只猴子,同样殴打了新来的猴子。替换了第三只猴子,也是如此。就这样,第四只、第五只猴子也接连被替换了。

    最终,笼子里面的五只猴子,尽管从未被泼冷水,仍然继续殴打任何试图爬上梯子的猴子。如果可以问猴子,为什么要殴打所有试图爬上梯子的成员,答案可能是:

    "这就是我们在这里做事的方式。"

    这个故事告诉我们,如果前人觉得某件事情不能做,阻力就会流传下来,阻止后来的人去做。

    但是,大多数人没有意识到,有时候情况会改变。二十年前不可能的事情今天也许并非不可能。比如,电动汽车以前是不可能的,现在随着电池技术的进步,才有可能。

    年轻人不知道为什么某事不能做,如果他们不怕阻力,就会去尝试那些不能做的事情。这就是为什么重大创新往往是年轻人做出来的原因。

    老年人通常看不到新的机会,因为他们相信有些事情是不可能的。年轻人在无知和热情推动下,愿意尝试那些不可能的事情。大多数年轻人会失败,但少数会成功。


    [阮一峰-科技爱好者周刊第 126 期]( http://www.ruanyifeng.com/blog/2020/09/weekly-issue-126.html)
    promisenev
        35
    promisenev  
       2020-09-30 14:04:52 +08:00
    你是你们团队的 code 老大吗?
    你能说服你们团队听你的吗?
    你记住,你不是独立开发者,你是公司的打工仔,是和别人同步协作的,你觉得不加也行,然后同事说加,你就加上,就行了,团队代码规范统一点,怎么了?
    aguesuka
        36
    aguesuka  
       2020-10-01 09:35:51 +08:00 via Android
    @codingbody 通过调查,我们发现这个故事的出处还是比较清楚的。大多数网站都提到,它出自一本名叫《为未来竞争( Competing for the Future )》的商业书籍(谷歌图书已经有电子版[1])。这本书的两位作者,一位是加里·哈梅尔( Gary Hamel ),美国著名的管理学专家;另一位是普哈拉( C. K. Prahalad ),密西根商学院的企业管理教授。他们在书里说,是从“一个朋友”处听来的实验。这个所谓的“实验”是否真实存在我们下文讨论。目前可以确定的是,将这个真实性存疑的“实验”写成通俗读本,引入大众文化圈的,正是这本商业管理领域的书籍。而最早将这个书本上的故事转载到互联网上是一家商业网站,他们则对这个故事有明确的定性,称它是一个“寓言”( fable )[2]。

    或许是受限于 2000 年之前网络的不发达,早先这个故事流传得并不广泛。直到 21 世纪,伴随着互联网的蓬勃发展,这个故事出现的频率越来越高,尤其是近三年。在传播的过程中,“湿猴理论”慢慢地发生了变化:人们不再提到它是从哪来的,也忘记了它本是一个商业寓言,而是将其描述得越来越像是真实的科学实验。它的细节也在传播中逐渐变化:不同版本中,猴子的数量各有不同;实验的步骤发生了改变;用作负面刺激的冷水也被改成了电击。最令生物学家抓狂的是,故事的某个中文版本中甚至出现了详细的实验数据[3]!显然作者唯恐它不像真实的实验,不惜“杜撰数据”(话说这可是学术圈的大忌)。

    在论述这个“实验”之后,各家都有对它的解读:有的教育人们不要扼杀新人的积极性;有的拿这些猴子作为模型讨论企业文化;还有的从中看到了人性的险恶。不过不管细节怎么改变,“实验”的流程、结果都与《为未来竞争》中那个寓言大致是一致的。

    猴子,猴子!你湿过么?
    既然故事本身只是个寓言,那么在真正的生物学和心理学研究中,有没有人做过类似实验呢?

    拿猴子作为实验对象的科学研究确实不少。不过,流言中那样向猴子泼冷水不让它们吃香蕉的实验是真没有。这个“实验”从它的设计本身来说就是极不规范的。既没有对照组,也有没任何措施排除干扰因素。而且在香蕉面前,猴子真的会止步于冷水吗?德克萨斯大学的人类学教授布兰布利特( Dr. Claud Bramblett )与猴子们共处了 30 多年,他对这个故事是这样评价的:如果你把香蕉放在猴子够得着的地方,就别想再拿回你的香蕉(大意如此,原话见参考资料[2]
    aguesuka
        37
    aguesuka  
       2020-10-01 09:37:18 +08:00 via Android
    @codingbody 太假了以至于我忍不住搜了一下
    xiadada
        38
    xiadada  
       2020-10-01 15:02:16 +08:00 via iPhone
    特地登陆回复你一下。 你们组其他人在这一点上都是彩笔。包括楼上不赞同的那几个观点。

    另外最后你加上了,也没有做错,是我我也会加,我只一旦知道自己是正确的时候就会暂时的服从,随便你怎么说怎么改 反正我是对的。我以后也会越来越对,让他们错下去。

    自己比别人好就行了。 持续努力 跳到更好的公司。

    ps 当你去更好一点的公司的时候,大家可能说 你说的对,但是这个不好说(还是彩笔)

    在你去更好的团队的(不是公司) 的时候 没有傻逼会在系统里遗留傻逼代码。
    siweipancc
        39
    siweipancc  
       2020-10-01 16:25:28 +08:00 via iPhone
    等一个用 redis 或者 mq 的后来者骂娘:D
    TransAM
        40
    TransAM  
       2020-10-01 20:25:45 +08:00 via Android
    尽量避免用 java 自带的序列化和反序列化机制,json 就是个不错的选择。
    312ybj
        41
    312ybj  
       2020-10-02 08:29:15 +08:00 via Android
    上次组长设计数据库,有很多字典表和冗余字段。但是这些是有道理的,后续系统扩展没这个东西就得重新设计一遍。我觉得代码是有生命周期的,完成功能不代表结束了,还得继续维护,后期可能追加功能。 你刚实习,可能没有接触过频繁的需求修改。其实吧,面向变化的编码设计才能更好的应对变化的需求,你同事加了序列化就避免了序列化异常,下次需要用序列化的时候就不会报错。技术都是拿过来用的,业务才能体现价值
    guyeu
        42
    guyeu  
       2020-10-02 14:18:44 +08:00
    @passerbytiny
    1. 序列化(Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程,反序列化是相反的过程。JSON 是一种可以存储或传输的数据格式规范,因此把对象转换成 JSON 的过程就是序列化,把 JSON 数据转换为对象的过程就是反序列化。这中间并不需要转出来的 JSON 和原来的对象一一对应,甚至不需要转出来的 JSON 能通过反序列化还原为原来的对象。不是很懂你对序列化有什么误解。
    2. 能举一个活得还不算差的基于 Java 序列化的 RPC 框架吗,我觉得同时支持多种序列化方式的 RPC 框架可能不能算,因为有选择的情况下,多数人应该不会选它。。
    3. 由于历史包袱,Java 中的确存在大量的不被推荐使用的 API,它们可能没有被显式标注废弃,但的确是在被逐渐减少使用,包括旧的 DateTime 相关工具类、clone 方法,也包括 Serializable 接口。
    passerbytiny
        43
    passerbytiny  
       2020-10-03 07:01:46 +08:00 via Android
    @guyeu
    1. 不可逆的序列化当然也是序列化,但要真把它当程序员用的序列化那特么的是想搞笑吗;如果不额外添加规则,把 Java 对象转换成 json 字符串是不可逆的。
    2. Apache Storm 备用序列化,Hibernate 一些特别情况下的值对象,2.9 及之前的 Dubbo (新版本不知道是否有重构);但“正在”不等于“已经”,“多说人不会去选择它”不等于“活得很差”;能够通用的序列化,也只有 JDK 的序列化,其它的都是框架自用标准(包括各种 Json 框架自带标
    准),到底谁是多数那还说不准。
    3. 如果你连 JDK 的标记都能有自己的解释,那就真得没啥可说了。

    最后再说一句,请不要为了反驳而反驳——我的观点以及论述方式都在说得是 Serializable 有它存在的必要性而不是 Serializable 好。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2999 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 14:47 · PVG 22:47 · LAX 07:47 · JFK 10:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.