桃城网站建设公司广告宣传方式有哪些
浅克隆:
实现Cloneable接口即可实现,浅克隆只对象内部的基础数据类型(包括包装类)被克隆,引用数据类型(负责对象)会被使用引用的方式传递。
简单来说,就是浅克隆属性如果是复杂对象,对象是不会被复制一份的。
示例如下:
package com.comleader.utils.test;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @Author: Daisen.Z* @Date: 2023/3/10 9:53* @Version: 1.0* @Description:*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Friend {private String name;private Integer age;private String home;
}
注意: 需要重新clone方法,将方法的protected改为public
package com.comleader.utils.test;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @Author: Daisen.Z* @Date: 2023/3/10 9:53* @Version: 1.0* @Description:*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person implements Cloneable {private String name;private Integer age;private String home;private Friend friend;@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}public static void main(String[] args) throws CloneNotSupportedException {Person person_old = new Person();person_old.setName("张三");person_old.setAge(18);person_old.setHome("chengdu");person_old.setFriend(new Friend("李四",19,"chongqin"));System.out.println("初始化下的person:" + person_old);Person person_clone = (Person) person_old.clone();person_clone.setName("张武");person_clone.setAge(19);person_clone.getFriend().setAge(20);System.out.println("克隆出来的person:" + person_clone);System.out.println("修改之后的person:" + person_clone);System.out.println("修改后的原person:" + person_old);}
}
运行Person中的main方法,
观察结果可以看出,修改Person的克隆对象的friend复杂属性时,原对象包括原对象的所有克隆对象friend熟悉都会被修改。
而修改String和Integer的则互不影响。
补充知识:
clonable接口的克隆方式,相比较于new对象的方式,不需要再计算内存分布,而是直接将内存区域分配给克隆对象,在大数据量的重复对象创建时可以使用clonable来优化性能。
深克隆:
深克隆的方式只能自己重新Cloneable方法或者序列化的方式实现。
重新克隆方法的方式:
1、 Friend实现Cloneable接口,并重写clone()方法。
@Data
@NoArgsConstructor
@AllArgsConstructor
class Friend implements Cloneable{private String name;private Integer age;private String home;@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}
}
2、 更改Person中的clone()方法
@Data
@NoArgsConstructor
@AllArgsConstructor
class Person implements Cloneable{private String name;private Integer age;private String home;private Friend friend;@Overridepublic Object clone() throws CloneNotSupportedException {Person person = (Person) super.clone();person.friend = (Friend) friend.clone();return person;}
}
这样克隆时,内部复杂对象也被克隆。
通过序列化对象的方式
如果当类中的属性存在数组(数组不能实现Cloneable接口)或者属性之间的关系比较复杂时,上面的方法都不能很好的实现深克隆了。
序列化的方式是让每个类都实现Serializable接口,然后通过序列化和反序列化操作达到深克隆的目的。
package test;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.*;@Data
@NoArgsConstructor
@AllArgsConstructor
class Person implements Serializable{private String name;private Integer age;private String home;private Friend friend;}@Data
@NoArgsConstructor
@AllArgsConstructor
class Friend implements Serializable {private String name;private Integer age;private String home;}public class CloneTest {public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {Person person_old = new Person();person_old.setName("张三");person_old.setAge(18);person_old.setHome("chengdu");person_old.setFriend(new Friend("李四",19,"chongqin"));System.out.println("初始化下的person:" + person_old);ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeObject(person_old); // 序列化ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);Person person_clone = (Person) objectInputStream.readObject(); //反序列化person_clone.setName("张武");person_clone.setAge(19);person_clone.getFriend().setAge(20);System.out.println("克隆出来的person:" + person_clone);System.out.println("修改之后的person:" + person_clone);System.out.println("修改后的原person:" + person_old);}
}
总结:
1、 浅克隆性能相比较new会有一些提高(很小),但是编码省了很多。
2、深克隆第一种实现方式同1。
3、深克隆的第二种实现方式在数据量多的情况下性能较差,但是当类熟悉特别多、对象占用空间特别大时会有较好效果,另外通过序列化可以将对象当前的形态以文件、IO流的方式保存下来,在需要时再进行加载转换,