来源:https://my.oschina.net/waylau...一般情况下,Java中不建议使用参数作为返回值。除了造成代码难以理解、语义不清晰等问题外,还可能埋下陷阱等着你掉坑里。问题背景比如有这么一段代码:@NamedpublicclassAService{privateSupplyAssignmentlocalSupply=newSupplyAssignment();@Inject私有BService服务;publicListcalcSupplyAssignment()ListsupplyList=bService.getLocalSupplyList(this.localSupply);...返回供应清单;}}上面代码中,服务A要调用服务B获取supplyList,但同时服务A要修改localSupply的status值,这就避免了修改calcSupplyAssignment接口(不想改返回的类型),将localSupply用作输入参数,同时也用作返回值。服务B的代码如下:@NamedpublicclassBService{publicListgetLocalSupplyList(SupplyAssignmentlocalSupply)SupplyAssignmentsupplyAssignment=this.getSupplyAssignment();//希望localSupply被重新分配并返回localSupply=supplyAssignment;…返回供应清单;}}在serviceB的代码里面,传入了服务A的入参localSupply,希望通过supplyAssignment重新赋值,然后返回一个新的值。但是,这样做是无效的。出现问题的原因首先要看编程语言中参数传递的类型:传值是指在调用函数时复制实参传递给函数,这样如果在函数中修改了参数,它不会影响实际参数。引用传递是指在调用函数时将实参的地址直接传递给函数,那么函数中参数的修改都会影响到实参。因为Java编程语言是按值传递的,因为Java没有指针的概念。也就是说,方法得到的是所有参数值的副本,方法不能修改传递给它的任何参数变量的内容。因此,在上面的代码中,服务A调用服务B时,??服务B的参数localSupply实际上是服务A的localSupply的一个副本,当然,两者都指向同一个地址对象supplyAssignment1。在服务B内部重新赋值参数localSupply时为localSupply=supplyAssignment,实际上只是重新赋值了B的参数localSupply,B的参数localSupply会指向一个新的地址对象supplyAssignment2。从上图可以清楚的看出,因此,服务A的localSupply和B的参数localSupply指向的是不同的对象,对B的参数localSupply的任何修改都不会影响服务A的localSupply原来的值。这就是问题的原因。你想让服务B修改服务A的输入参数的状态,并将更改后的值返回给服务A,但是它不起作用。解决方案一:不要把入参作为返回值有时候你真的想把入参作为返回值,那就看解决方案二。解决方案二:不要给参数赋新的对象。这种解决方案是直接在输入参数的对象上修改状态,而不是分配新的对象。还是这张图:在这张图中,只要我们一直在修改B的参数localSupply中supplyAssignment1的状态值,就可以将结果反馈给服务A的localSupply。如何实现?看下面的代码:@NamedpublicclassBService{publicListgetLocalSupplyList(SupplyAssignmentlocalSupply)SupplyAssignmentsupplyAssignment=this.getSupplyAssignment();//不能创建对localSupply的新引用,只能重新分配属性BeanUtils.copyProperties(supplyAssignment,localSupply);...返回供应清单;}}在上面的方法中,我们使用了Spring的工具类BeanUtils。该类的copyProperties方法的本质是将supplyAssignment的属性值赋值给localSupply的属性。这意味着我们正在修改B的参数localSupply上的属性,而不是创建新对象。近期热点文章推荐:1.1000+Java面试题及答案(2022最新版)2.厉害了!Java协程来了。..3.SpringBoot2.x教程,太全面了!4.不要用爆破爆满画面,试试装饰者模式,这才是优雅的方式!!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!