Java 使用引用传递来修改值,这样做好吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
zzfer
V2EX    程序员

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

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

    今天在代码审核的时候看到这么一段代码,在 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     Solana     1270 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 17:16 PVG 01:16 LAX 10:16 JFK 13:16
    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