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

Java 使用引用传递来修改值,这样做好吗?

  •  
  •   zzfer · 2021-10-15 15:49:23 +08:00 · 3603 次点击
    这是一个创建于 1129 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天在代码审核的时候看到这么一段代码,在 setProjectInfo 方法没有返回内容,但在方法体内给 list set 了值,想了下,是 Java 引用类型可以改变参数的值,这样写确实可行

    	if (!CollectionUtils.isEmpty(list)){
                cmService.setProjectInfo(list);
            }
        	return list;
    

    但如果是我写同样的需求,肯定是返回类型是 list<>,然后结果 return 给 list 。我不知道哪种写法好,想问问大家

    	if (!CollectionUtils.isEmpty(list)){
                list = cmService.setProjectInfo(list);
            }
        	return list;
    
    24 条回复    2021-10-17 01:05:36 +08:00
    hidemyself
        1
    hidemyself  
       2021-10-15 16:02:11 +08:00
    额,我都是用第一种写法。
    zydxn
        2
    zydxn  
       2021-10-15 16:04:39 +08:00
    看不出你这么给方法 setProjectInfo 改成加上返回值在你的业务代码里有什么意义

    如果你的某个实体里有字段属性是 Collection,你也要把 set 方法改成有返回值的么
    crazypig14
        3
    crazypig14  
       2021-10-15 16:05:19 +08:00
    第二种好在支持链式调用,第一种方法名起好一点就好,比如叫 append 啥啥好点
    liuxey
        4
    liuxey  
       2021-10-15 16:05:28 +08:00   ❤️ 3
    一般传递给不受信任的方法时要用 ImmutableList,比如:

    ImmutableList<XXX> list = ...;
    if (!CollectionUtils.isEmpty(list)){
    list2 = cmService.setProjectInfo(list);
    }
    return list2;

    但实际操情况中 list 内部变量会因为是 Mutable 而被隐性破坏:list.get(0).setXXX(x);

    所以爱咋写咋写
    Jooooooooo
        5
    Jooooooooo  
       2021-10-15 16:09:19 +08:00
    没有区别.
    AoEiuV020
        6
    AoEiuV020  
       2021-10-15 16:09:32 +08:00
    挺常见的做法,
    按我习惯而言,一般用前者,
    如果是必须复制一个新的列表,不能动原 list 才会用第二种写法返回个新的,
    chendy
        7
    chendy  
       2021-10-15 16:14:07 +08:00   ❤️ 1
    要么 改原 List,不返回(副作用方法)
    要么 返回新的 List,不改原 List (无副作用方法)
    把参数改了又返回出去真的很迷惑
    zzfer
        8
    zzfer  
    OP
       2021-10-15 16:14:44 +08:00
    @hidemyself 我一直都是第二种,也不知道怎么养成的代码习惯。

    @zydxn 最大的意义就是可读性更好吧。实体字段是给实体内 set 值,这个相当于你在 set 中修改你要 set 的值,不是一个概念

    @crazypig14 确实支持链式调用也是一个好处。我感觉可读性比第一种高点

    @liuxey 学到了
    shellus
        9
    shellus  
       2021-10-15 16:31:40 +08:00
    ```
    修手机方法 1:
    var 我的手机
    修好的手机=维修店.全面修复(我的手机)
    ```
    ```
    修手机方法 2:
    var 我的手机
    工具 = 维修店.购买工具(xxx)
    技术 = 维修店.学习技术(xxx)
    修好的手机=我.修理(我的手机,工具,技术)
    ```

    第一个写法,简单,但是你不知道维修店对你的手机做了啥
    第二个方法,复杂,你需要在你的方法里写很多无关的东西

    但是无论如何,都是用返回值接收,因为下面这种会看起来很怪异

    ```
    // 我的手机 坏的
    维修店.全面修复(我的手机)
    // 我的手机 好了
    ```
    wolfie
        10
    wolfie  
       2021-10-15 16:39:08 +08:00
    list = 意义是什么?
    setProjectInfo 还会给你另一个 List ?
    pelloz
        11
    pelloz  
       2021-10-15 16:44:54 +08:00
    这种时候,一般不用 setProjectInfo,用 fillProjectInfo 会比较好。在 java 的语境下,set/get 大部分用于属性修改获取,在 service 中用 set/get 会让人觉得你可能是想改这个 service 的某个属性。
    A555
        12
    A555  
       2021-10-15 17:10:34 +08:00
    setProjectInfo 不太好,看上去像是给 cmService set 值
    GiftedJarvis
        13
    GiftedJarvis  
       2021-10-15 17:19:13 +08:00
    我记得<<重构>>和<<clean code>>的建议都是不改变方法参数, 但工作中, 我还是为了方便修改参数并返回
    Aliberter
        14
    Aliberter  
       2021-10-15 17:24:36 +08:00
    如果你装了 sonar 的规范检测插件,第二种写法会警告你这是冗余的写法,会让你删除多余的返回值。
    Leviathann
        15
    Leviathann  
       2021-10-15 17:54:13 +08:00
    没什么区别
    返回的都是同一个 list
    除非是用 stream api 新创建的 list,那就是 immutable 的
    Leviathann
        16
    Leviathann  
       2021-10-15 17:58:38 +08:00
    不过有个可能的好处,list=xxxService.xxxprocess(list)
    idea 会告诉你 list 被改过,变量颜色会标记成被重新赋值过的,稍微有点提示的作用,告诉看的人 list 被改过
    simonlu9
        17
    simonlu9  
       2021-10-15 18:04:27 +08:00
    很大区别,我就踩过一个坑,list 是不可修改,结果你调用里面的增加或删除元素,就会报错。所以要返回值
    codingbody
        18
    codingbody  
       2021-10-15 19:38:54 +08:00 via iPhone
    java 只有值传递
    yazinnnn
        19
    yazinnnn  
       2021-10-15 21:57:36 +08:00
    我觉得都挺扯淡的,传给你不可变的集合你的程序就挂了
    walpurgis
        20
    walpurgis  
       2021-10-15 23:37:35 +08:00 via iPhone
    副作用方法和纯函数一定要明确区分
    Vegetable
        21
    Vegetable  
       2021-10-15 23:39:32 +08:00
    不要使用第二种
    说实话这种内部的 list 就不该暴露出来
    Vegetable
        22
    Vegetable  
       2021-10-15 23:40:34 +08:00
    看错了,当我没说哈哈
    VeryZero
        23
    VeryZero  
       2021-10-16 00:24:42 +08:00
    第一种调用栈比较深的时候就很蛋疼了。维护过这种代码,简直折磨
    husher123
        24
    husher123  
       2021-10-17 01:05:36 +08:00
    虽然我也写过 1,但是更喜欢 2,可以链式调用 0.0
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1101 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 18:31 · PVG 02:31 · LAX 10:31 · JFK 13:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.