原文网址:Java的List之坑系列--ArrayList的浅拷贝问题_IT利刃出鞘的博客-CSDN博客
本文介绍ArrayList的浅拷贝问题的原因和解决方案。
问个问题:先new ArrayList创建了list1并用add添加对象,再new ArrayList创建了list2,然后list2.addAll(list1)。此时如果list1的数据变了,那么list2的数据是否改变?
答案:会改变,因为addAll是浅拷贝(拷贝引用地址)。new ArrayList(list1)也是同样的结果。
controller
- package com.knife.controller;
-
- import com.knife.entity.User;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.ArrayList;
- import java.util.List;
-
- @RestController
- public class HelloController {
-
- @GetMapping("/test")
- public String test() {
- List
userList = new ArrayList<>(); - User user1 = new User();
- user1.setId(1L);
- user1.setUserName("Tony");
-
- User user2 = new User();
- user2.setId(2L);
- user2.setUserName("Pepper");
-
- userList.add(user1);
- userList.add(user2);
- System.out.println("旧列表(修改前):" + userList);
-
- List
newUserList = new ArrayList<>(userList); - newUserList.get(0).setUserName("AA");
- System.out.println("旧列表(修改后):" + userList);
- System.out.println("新列表(修改后):" + newUserList);
-
- return "test success";
- }
- }
entity
- package com.knife.entity;
-
- import lombok.Data;
-
- @Data
- public class User {
- private Long id;
-
- private String userName;
-
- }
后端结果:(旧list的对象也被改变了)
- 旧列表(修改前):[User(id=1, userName=Tony), User(id=2, userName=Pepper)]
- 旧列表(修改后):[User(id=1, userName=AA), User(id=2, userName=Pepper)]
- 新列表(修改后):[User(id=1, userName=AA), User(id=2, userName=Pepper)]
打断点分析

可以发现,旧的list和新的list,里边的user对象都是同一个引用。
代码追踪
代码的调用关系如下所示:
- java.util.ArrayList#ArrayList(java.util.Collection extends E>)
- Arrays.copyOf(elementData, size, Object[].class);
- System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength));
也就是说:System.arrayCopy是浅拷贝。
上边是文章的部分内容,为便于维护,全文已转移到此网址:Java的List之坑-ArrayList的浅拷贝问题 - 自学精灵