深拷贝VS浅拷贝
-
深拷贝将对象及值复制过来,两个对象修改其中任意的值,另一个值不会改变。
-
浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意值,另一个值都会随之改变。
深拷贝和浅拷贝会增加内存吗?
深拷贝:增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。
浅拷贝:增加了一个指针指向已存在的内存地址。
为什么要使用克隆?
对象的拷贝需要使用克隆,如果想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要使用克隆了,Java语言中克隆针对的是类的实例。
如何实现对象克隆?
实现Cloneable接口并重写Object类中的clone()方法。
/*1、所有对象都实现克隆方法;*/
public class CloneExample1 {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address(1,"广州");
People people = new People(1,"Java", address);
// 克隆
People people1 = people.clone();
// 修改原型
people1.setId(2);
people1.address.setCity("深圳");
// 输出比对结果
System.out.println("原型对象:" + people);
System.out.println("克隆对象:" + people1);
}
// 用户类
static class People implements Cloneable{
private Integer id;
private String name;
private Address address;
public People(Integer id, String name, Address address) {
this.id = id;
this.name = name;
this.address = address;
}
@Override
protected People clone() throws CloneNotSupportedException {
People people = (People)super.clone();
people.setAddress(this.address.clone());
return people;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
", name='" + name + '\'' +
", address=" + address +
'}';
}
public Integer getId() {
return id;
}
public People setId(Integer id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public People setName(String name) {
this.name = name;
return this;
}
public Address getAddress() {
return address;
}
public People setAddress(Address address) {
this.address = address;
return this;
}
}
// 地址类
static class Address implements Cloneable{
private Integer id;
private String city;
public Address(Integer id, String city) {
this.id = id;
this.city = city;
}
@Override
protected Address clone() throws CloneNotSupportedException {
return (Address)super.clone();
}
@Override
public String toString() {
return "Address{" +
"id=" + id +
", city='" + city + '\'' +
'}';
}
public Integer getId() {
return id;
}
public Address setId(Integer id) {
this.id = id;
return this;
}
public String getCity() {
return city;
}
public Address setCity(String city) {
this.city = city;
return this;
}
}
}
实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
package clone.deep.example1;
import java.io.*;
/*3、使用 JDK 自带的字节流实现深克隆;
* 通过字节流将原型对象的值写进内存,然后再从内存中读取数据进行克隆。
* 因为是从内存中读取值所以不存在共享内存地址。
注意:原型对象以及引用对象都要实现Serializable 接口,
* 标识自己可以被序列化,否则会抛出异常
* (java.io.NotSerializableException)。
*/
public class CloneExample2 {
public static void main(String[] args) {
Address address = new Address(1,"广州");
People people1 = new People(1,"Java", address);
// 通过字节流实现克隆
People people2 = StreamClone.clone(people1);
// 修改原型
people1.setId(2);
people1.getAddress().setCity("深圳");
// 输出比对结果
System.out.println("原型对象:" + people1);
System.out.println("克隆对象:" + people2);
}
static class StreamClone{
/**
* 通过字节流实现克隆
*/
public static <T extends Serializable> T clone(T obj) {
T cloneObj = null;
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bo);
oos.writeObject(obj);
oos.close();
// 分配内存,写入原型对象,生成新对象
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
// 返回生成的新对象
cloneObj = (T) oi.readObject();
oi.close();
} catch (Exception e) {
e.printStackTrace();
}
return cloneObj;
}
}
// 用户类
static class People implements Serializable{
private Integer id;
private String name;
private Address address;
public People(Integer id, String name, Address address) {
this.id = id;
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
", name='" + name + '\'' +
", address=" + address +
'}';
}
public Integer getId() {
return id;
}
public People setId(Integer id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public People setName(String name) {
this.name = name;
return this;
}
public Address getAddress() {
return address;
}
public People setAddress(Address address) {
this.address = address;
return this;
}
}
// 地址类
static class Address implements Serializable {
private Integer id;
private String city;
public Address(Integer id, String city) {
this.id = id;
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"id=" + id +
", city='" + city + '\'' +
'}';
}
public Integer getId() {
return id;
}
public Address setId(Integer id) {
this.id = id;
return this;
}
public String getCity() {
return city;
}
public Address setCity(String city) {
this.city = city;
return this;
}
}
}
使用第三方工具实现深克隆:
JDK 自带的字节流实现深克隆org.apache.commons.lang.SerializationUtils.clone(Serializable object)
/**
* 深克隆实现方式四:通过 apache.commons.lang 实现
*/
public class CloneExample3 {
public static void main(String[] args) {
Address address = new Address(1,"广州");
People people1 = new People(1,"Java", address);
// 通过字节流实现克隆
People people2 = (People) SerializationUtils.clone(people1);
// 修改原型
people1.setId(2);
people1.getAddress().setCity("深圳");
// 输出比对结果
System.out.println("原型对象:" + people1);
System.out.println("克隆对象:" + people2);
}
// 用户类
static class People implements Serializable{
private Integer id;
private String name;
private Address address;
public People(Integer id, String name, Address address) {
this.id = id;
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
", name='" + name + '\'' +
", address=" + address +
'}';
}
public Integer getId() {
return id;
}
public People setId(Integer id) {
this.id = id;
return this;
}
public String getName() {
return name;
}
public People setName(String name) {
this.name = name;
return this;
}
public Address getAddress() {
return address;
}
public People setAddress(Address address) {
this.address = address;
return this;
}
}
// 地址类
static class Address implements Serializable {
private Integer id;
private String city;
public Address(Integer id, String city) {
this.id = id;
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"id=" + id +
", city='" + city + '\'' +
'}';
}
public Integer getId() {
return id;
}
public Address setId(Integer id) {
this.id = id;
return this;
}
public String getCity() {
return city;
}
public Address setCity(String city) {
this.city = city;
return this;
}
}
}
标签:return,String,Address,public,VS,address,拷贝,id
From: https://www.cnblogs.com/haveanicedayfh/p/16803619.html