深拷贝和浅拷贝的区别

    科技2025-08-06  18

    文章目录

    浅拷贝和深拷贝的定义常见的浅拷贝方式常见的深拷贝方式

    浅拷贝和深拷贝的定义

    浅拷贝:只是将代表源对象的地址拷贝给了另外一个变量,该变量和原来变量都指向同一个地址,当源对象的发生变化时,拷贝对象和源对象都会发生变化深拷贝:创建了新空间来存储源对象的值,源对象和拷贝对象存放的地址不一样,两个对象任意一个发生变化都不会影响另外一个。

    常见的浅拷贝方式

    (1)一个引用类型变量直接赋值给另一个变量 (2)BeaUtil.copyProperties()

    常见的深拷贝方式

    (1)通过构造器或new的方式 (2)重写继承至Object方法的clone方法,并实现Cloneable接口 如果在没有实现Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常,实现Cloneable 接口的目的是:为了告知JVM,此对象允许拷贝

    public class Main { public static void main(String[] args) throws CloneNotSupportedException { User user = new User(1, "测试"); User user1 = user.clone(); System.out.println(user1); } } class User implements Cloneable{ private Integer id; private String name; //必须重写此方法 @Override protected User clone() throws CloneNotSupportedException { return (User)super.clone(); } public User(Integer id, String name) { this.id = id; this.name = name; } }

    注意: 当通过Cloneable接口实现深拷贝时,拷贝的源对象的属性如果是引用对象(String类型除外),则该属性也需要实现Cloneable接口,并覆写clone方法,否则该属性是进行的浅拷贝。

    String类型属性:Clonable拷贝后两个对象的相同属性指向了通过字符串,但字符串是不可以修改的,存放在常量池中,当其中1个对象的该属性指向另个字符串时,另外一个对象的属性的引用仍指向原字符串。 public class ProtoTypeDemo { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(); person.setId(1L); person.setName("test"); User user = new User(); user.setUsername("测试"); person.setUser(user); Person person1 = person.clone(); User user1 = user.clone(); user1.setUsername("cs"); person1.setUser(user1); System.out.println(person1);//Person{id=1, name='test', user=User{username='cs'}} System.out.println(person);//Person{id=1, name='test', user=User{username='测试'}} } } public class Person implements Cloneable { private Long id; private String name; private User user; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public Person clone() throws CloneNotSupportedException { return (Person) super.clone(); } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", user=" + user + '}'; } } public class User implements Cloneable{ private String username; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Override public User clone() throws CloneNotSupportedException { return (User) super.clone(); } @Override public String toString() { return "User{" + "username='" + username + '\'' + '}'; } }

    (3)序列化的方式:FastJson、Gson等都可以

    class Main{ public static void main(String[] args) { User user = new User(1, "测试"); //序列化 String s = JSONObject.toJSONString(user); //反序列化 System.out.println(s); User user1 = JSON.parseObject(s, User.class); System.out.println(user1); } } public class User { private Integer id; private String name; public User(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
    Processed: 0.012, SQL: 8