preface

I have been writing PHP for the past two months. I feel that I haven’t written Java code for a long time, because I have to rebuild the company’s Java project recently, and then PICK up Java. In the process of writing the code, there is a point before actually did not pay attention to, almost stepped on a foot, through this article to briefly record.

Java value passing and reference passing

Data types in Java fall into two broad categories, primitive types and object types. Accordingly, variables have two types: primary and reference.

  • A primitive variable holds the original value, that is, the value it represents is the value itself;
  • A variable of a reference type holds a reference value. The “reference value” refers to an address in memory space and represents a reference to an object, not the object itself, which is stored at the address represented by the reference value.

Value passing is limited to four classes of eight basic data types:

Excluding the four basic types, the others are all objects, or reference types, including class types, interface types, and arrays.

In terms of memory allocation on the stack, I’m not going to draw that, I’m not going to illustrate that, there’s a lot of stuff on the Internet.

reference

Let’s look at passing by reference with ArrayList. I define the following two objects:

@Data
@NoArgsConstructor
public class DeptDTO {
    /** * Dept_code */
    private String deptCode;

    /** * Dept_name */
    private String deptName;

    /** * Dept_level */
    private Integer deptLevel;
}
Copy the code

Sample code:

public static void main(String[] args) {
    DeptDTO dept1 = new DeptDTO();
    DeptDTO dept2 = new DeptDTO();

    dept1.setDeptCode("111");;
    dept2.setDeptCode("222");;

    List<DeptDTO> deptList = new ArrayList<>();
    deptList.add(dept1);
    deptList.add(dept2);

    for (DeptDTO deptRecord : deptList) {
        System.out.println("Print deptCode:" + deptRecord.getDeptCode());
    }

    // Get the element, which is actually a reference to the obtained element. Modifying the element value affects the value of the personList
    DeptDTO dept = deptList.get(0);
    dept.setDeptCode("333");

// // Changing this value directly affects the value of deptList. Deptlist.add () stores a reference to an object
// dept.setDeptCode("444");

    for (DeptDTO deptRecord : deptList) {
        System.out.println("Print deptCode:"+ deptRecord.getDeptCode()); }}/ / output:
// Print deptCode:111
// Print deptCode:222
// Print deptCode:333
// Print deptCode:222
Copy the code

We found that getting the values in the deptList and then modifying them directly affected the values in the deptList because we got the values in the deptList. For example, if PHP gets array data, it is passed by value, not by reference. If you need to modify the data in the array, you need to directly modify the index value corresponding to the deptList.

Let’s release the comment above:

Deptlist.add () stores a reference to an object
dept1.setDeptCode("444");

/ / output:
// Print deptCode:111
// Print deptCode:222
// Print deptCode:444
// Print deptCode:222
Copy the code

Dept, dept1, deptList.get(0), deptList.get(0), deptList.get(0), deptList.get(0), deptList.get(0), deptList.get(0), deptList.get(0), deptList.get(0)

System.out.println(System.identityHashCode(dept));
System.out.println(System.identityHashCode(dept1));
System.out.println(System.identityHashCode(deptList.get(0)));
/ / output:
/ / 1612799726
/ / 1612799726
/ / 1612799726
Copy the code

Problem is introduced into

My problem is with passing references using ArrayList and HashMap. Let’s add another object:

@Data
public class DeptCalcuateDTO  extends DeptDTO {
    /**
     * 计算数据
     */
    private Integer calculateNumber;
}
Copy the code

List< DeptDTO > A, now I need to convert the data in A to DeptTreeDTO B, I write the following code:

DeptCalcuateDTO deptCalcuateDTO = (DeptCalcuateDTO) dept1;
deptCalcuateDTO.setDeptCode("333");
Copy the code

If the above syntax is valid, since it is passed by reference, modifying deptCalcuateDTO will affect the data in A, but A is the basic data, so it is not allowed to be modified, which violates my original intention.

It turns out that I was overthinking it, because when I wrote the Deom use case, I realized that the above cast would not work because it would throw a ClassCastException() exception, but C++ supports this type of cast.

To solve the problem

In fact, it is A copy problem. I could have directly assigned the data in A to B, but the reality is that there are too many attributes in it. I didn’t want to convert them every time, so I borrowed A tool library.

Import packages first:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.2. 0.Final</version>
</dependency>
Copy the code

Add entity conversion interface:

@Mapper(componentModel = "spring")
public interface AppDeptConverter {
    AppDeptConverter INSTANCE = Mappers.getMapper(AppDeptConverter.class);

    DeptCalcuateDTO toDeptCalcuate(DeptDTO deptDTO);
}
Copy the code

Test cases:

public static void main(String[] args) {
    DeptDTO dept1 = new DeptDTO();
    DeptDTO dept2 = new DeptDTO();
    dept1.setDeptCode("111");
    dept2.setDeptCode("222");

    List<DeptDTO> deptList = new ArrayList<>();
    deptList.add(dept1);
    deptList.add(dept2);

    DeptCalcuateDTO deptCalcuateDTO =  AppDeptConverter.INSTANCE.toDeptCalcuate(dept1);
    deptCalcuateDTO.setDeptCode("333");

    for (DeptDTO deptRecord : deptList) {
        System.out.println("Print deptCode:"+ deptRecord.deptCode); }}/ / output:
// Print deptCode:111
// Print deptCode:222
Copy the code

What this tool does is very simple. It generates A DeptCalcuateDTO object and assigns the values of A to B in turn, as shown in mapstruct.org/

Welcome everyone to like a lot, more articles, please pay attention to the wechat public number “Lou Zai advanced road”, point attention, do not get lost ~~