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

2021-10-15 15:49:23 +08:00
 zzfer

今天在代码审核的时候看到这么一段代码,在 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;
3650 次点击
所在节点    程序员
24 条回复
hidemyself
2021-10-15 16:02:11 +08:00
额,我都是用第一种写法。
zydxn
2021-10-15 16:04:39 +08:00
看不出你这么给方法 setProjectInfo 改成加上返回值在你的业务代码里有什么意义

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

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

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

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

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

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

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

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

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

```
// 我的手机 坏的
维修店.全面修复(我的手机)
// 我的手机 好了
```
wolfie
2021-10-15 16:39:08 +08:00
list = 意义是什么?
setProjectInfo 还会给你另一个 List ?
pelloz
2021-10-15 16:44:54 +08:00
这种时候,一般不用 setProjectInfo,用 fillProjectInfo 会比较好。在 java 的语境下,set/get 大部分用于属性修改获取,在 service 中用 set/get 会让人觉得你可能是想改这个 service 的某个属性。
A555
2021-10-15 17:10:34 +08:00
setProjectInfo 不太好,看上去像是给 cmService set 值
GiftedJarvis
2021-10-15 17:19:13 +08:00
我记得<<重构>>和<<clean code>>的建议都是不改变方法参数, 但工作中, 我还是为了方便修改参数并返回
Aliberter
2021-10-15 17:24:36 +08:00
如果你装了 sonar 的规范检测插件,第二种写法会警告你这是冗余的写法,会让你删除多余的返回值。
Leviathann
2021-10-15 17:54:13 +08:00
没什么区别
返回的都是同一个 list
除非是用 stream api 新创建的 list,那就是 immutable 的
Leviathann
2021-10-15 17:58:38 +08:00
不过有个可能的好处,list=xxxService.xxxprocess(list)
idea 会告诉你 list 被改过,变量颜色会标记成被重新赋值过的,稍微有点提示的作用,告诉看的人 list 被改过
simonlu9
2021-10-15 18:04:27 +08:00
很大区别,我就踩过一个坑,list 是不可修改,结果你调用里面的增加或删除元素,就会报错。所以要返回值
codingbody
2021-10-15 19:38:54 +08:00
java 只有值传递
yazinnnn
2021-10-15 21:57:36 +08:00
我觉得都挺扯淡的,传给你不可变的集合你的程序就挂了
walpurgis
2021-10-15 23:37:35 +08:00
副作用方法和纯函数一定要明确区分

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

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

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

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

© 2021 V2EX