Normally, input parameters are not recommended as return values in Java. In addition to making your code difficult to understand and semantic, it can also be a trap for you to fall into.

The problem background

For example, here is the code:

@Named public class AService { private SupplyAssignment localSupply = new SupplyAssignment(); @Inject private BService bervice; public List<Supply> calcSupplyAssignment() List<Supply> supplyList = bService.getLocalSupplyList(this.localSupply); ... return supplyList; }}Copy the code

In the above code, service A wants to call service B to obtain the supplyList, but at the same time, service A wants to change the state value of localSupply. LocalSupply is used as an input parameter but also as a return value.

The service B code is as follows:

@Named public class BService { public List<Supply> getLocalSupplyList (SupplyAssignment localSupply) SupplyAssignment supplyAssignment = this.getSupplyAssignment(); // supplyAssignment = supplyAssignment; ... return supplyList; }}Copy the code

Inside the service B code, service A’s input parameter, localSupply, is passed in and expected to be re-assigned by supplyAssignment and return A new value. However, this is not effective.

Question why

Let’s take a look at the types of arguments passed in programming languages:

  • Pass by value means that a copy of the actual parameter is passed to the function when the function is called, so that the actual parameter is not affected if the parameter is changed.
  • Pass by reference refers to that the address of the actual parameter is directly passed to the function when the function is called. Then the modification of the parameter in the function will affect the actual parameter.

Because the Java programming language uses value passing, because Java has no concept of Pointers. That is, a method gets a copy of all the parameter values and cannot modify the contents of any parameter variables passed to it.

Thus, when service A calls service B, service B’s parameter localSupply is actually A copy of Service A’s supplyAssignment1.

SupplyAssignment = supplyAssignment; supplyAssignment = supplyAssignment; supplyAssignment = supplyAssignment The argument localSupply to B points to a new address object, supplyAssignment2.

As you can clearly see from the figure above, service A’s parameter localSupply and B’s parameter localSupply already point to different objects, and any changes to B’s parameter localSupply will not affect service A’s original value of localSupply. This is where the problem arises. You want service B to change the state of service A’s input and return the changed value to service A, but it doesn’t work.

The solution

Option 1: Do not use an input parameter as a return value

Of course, this is the clearest and easiest to understand, but it can lead to changes in the return types of some interfaces.

Sometimes you do want an input to return a value, so look at plan 2.

Option 2: Do not assign a new object to an input parameter

The solution is to change the state directly on the input object without assigning the new object. Here’s the same picture:

In this diagram, as long as we modify the state value of supplyAssignment1 in B, the result can be fed back to localSupply of service A. How to do that? Take a look at this code:

@Named public class BService { public List<Supply> getLocalSupplyList (SupplyAssignment localSupply) SupplyAssignment supplyAssignment = this.getSupplyAssignment(); Beanutils.copyproperties (supplyAssignment, localSupply); ... return supplyList; }}Copy the code

In the above method, we use the Spring utility class BeanUtils, whose copyProperties method essentially assigns the value of the supplyAssignment property to the property of localSupply. This means that we are modifying the property on B’s parameter localSupply, rather than creating a new object.

Welcome to pay attention to the public number [code farming blossom] learn to grow together I will always share Java dry goods, will also share free learning materials courses and interview treasure book reply: [computer] [design mode] [interview] have surprise oh