在开发过程中,创建多个数据相同的对象,每次new都开销比较大,在这里可以使用对象克隆,以先创建的原型对象为模板进行对象的复制。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用
在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址
?
public class Person implements ?Cloneable{
??
? ? ? int num;
? ? ? String name;
??
? ? ?public Person() {
? ? }
??
? ? ?public Person(int num, String name) {
? ? ? ? ?this.num = num;
? ? ? ? ?this.name = name;
? ? }
??
? ? ?public int getNum() {
? ? ? ? ?return num;
? ? }
??
? ? ?public void setNum(int num) {
? ? ? ? ?this.num = num;
? ? }
??
? ? ?public String getName() {
? ? ? ? ?return name;
? ? }
??
? ? ?public void setName(String name) {
? ? ? ? ?this.name = name;
? ? }
??
??
??
? ? ?@Override
? ? ?protected Person clone() throws CloneNotSupportedException {
? ? ? ? ?Person person = (Person)super.clone();
? ? ? ? ?return person;
? ? }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Person{" +
? ? ? ? ? ? ? ? ?"num=" + num +
? ? ? ? ? ? ? ? ?", name='" + name + '\'' +
? ? ? ? ? ? ? ? ?'}';
? ? }
?}
?public class Test {
??
? ? ?public static void main(String[] args) throws CloneNotSupportedException {
??
? ? ? ? ?Person p1 = new Person(100,"jim");
? ? ? ? ?Person p2 =p1.clone();//clone方法 返回一个新对象
? ? ? ? ?p2.name = "tom";
? ? ? ? ?System.out.println(p1);//100 ,jim
? ? ? ? ?System.out.println(p2);//100 tom
??
? ? ? ? ?System.out.println(p1==p2);//false
??
? ? }
?}
在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制
?public class Person implements ?Cloneable{
??
? ? ? int num;
? ? ? String name;
? ? ? Address address;
??
? ? ?public Person() {
??
? ? }
??
? ? ?public Person(int num, String name) {
? ? ? ? ?this.num = num;
? ? ? ? ?this.name = name;
? ? }
??
? ? ?public int getNum() {
? ? ? ? ?return num;
? ? }
??
? ? ?public void setNum(int num) {
? ? ? ? ?this.num = num;
? ? }
??
? ? ?public String getName() {
? ? ? ? ?return name;
? ? }
??
? ? ?public void setName(String name) {
? ? ? ? ?this.name = name;
? ? }
??
? ? ?public Address getAddress() {
? ? ? ? ?return address;
? ? }
??
? ? ?public void setAddress(Address address) {
? ? ? ? ?this.address = address;
? ? }
??
? ? ?@Override
? ? ?protected Person clone() throws CloneNotSupportedException {
? ? ? ? ?Person person = (Person)super.clone();
? ? ? ? ?person.address = address.clone(); ? //深度复制 联同person中关联的对象也一同克隆.
? ? ? ? ?return person;
? ? }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Person{" +
? ? ? ? ? ? ? ? ?"num=" + num +
? ? ? ? ? ? ? ? ?", name='" + name + '\'' +
? ? ? ? ? ? ? ? ?", address=" + address +
? ? ? ? ? ? ? ? ?'}';
? ? }
?}
??
?public class Address ?implements Cloneable{
??
? ? ? String ?address;
??
? ? ?public String getAddress() {
? ? ? ? ?return address;
? ? }
??
? ? ?public void setAddress(String address) {
? ? ? ? ?this.address = address;
? ? }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Address{" +
? ? ? ? ? ? ? ? ?"address='" + address + '\'' +
? ? ? ? ? ? ? ? ?'}';
? ? }
??
? ? ? @Override
? ? ?protected Address clone() throws CloneNotSupportedException {
? ? ? ? ?return (Address) super.clone();
? ? }
?}
?
public class Address ?implements Serializable {
??
? ? ? String ?address;
??
? ? ?public String getAddress() {
? ? ? ? ?return address;
? ? }
??
? ? ?public void setAddress(String address) {
? ? ? ? ?this.address = address;
? ? }
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Address{" +
? ? ? ? ? ? ? ? ?"address='" + address + '\'' +
? ? ? ? ? ? ? ? ?'}';
? ? }
??
?}
?
public class Person implements Serializable {
??
? ? ? int num;
? ? ? String name;
? ? ? Address address;
??
? ? ?public Person() {
? ? }
??
? ? ?public Person(int num, String name) {
? ? ? ? ?this.num = num;
? ? ? ? ?this.name = name;
? ? }
??
? ? ?public int getNum() {
? ? ? ? ?return num;
? ? }
??
? ? ?public void setNum(int num) {
? ? ? ? ?this.num = num;
? ? }
??
? ? ?public String getName() {
? ? ? ? ?return name;
? ? }
??
? ? ?public void setName(String name) {
? ? ? ? ?this.name = name;
? ? }
??
? ? ?public Address getAddress() {
? ? ? ? ?return address;
? ? }
??
? ? ?public void setAddress(Address address) {
? ? ? ? ?this.address = address;
? ? }
??
? ? ?/**
? ? ? * 自定义克隆方法
? ? ? * @return
? ? ? */
? ? ?public Person myclone() {
? ? ? ? ? ? ?Person person = null;
? ? ? ? ? ? ? ?try { // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝
? ? ? ? ? ? ? ? ? ? ? ByteArrayOutputStream baos = new ByteArrayOutputStream();
? ? ? ? ? ? ? ? ? ? ? ?ObjectOutputStream oos = new ObjectOutputStream(baos);
? ? ? ? ? ? ? ? ? ? ? ?oos.writeObject(this);
? ? ? ? ? ? ?// 将流序列化成对象
? ? ? ? ? ? ? ? ? ? ?ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
? ? ? ? ? ? ? ? ? ? ? ObjectInputStream ois = new ObjectInputStream(bais);
? ? ? ? ? ? ? ? ? ? ? person = (Person) ois.readObject();
? ? ? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? } catch (ClassNotFoundException e) {
? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? return person;
? ? ? ? ? }
??
??
? ? ?@Override
? ? ?public String toString() {
? ? ? ? ?return "Person{" +
? ? ? ? ? ? ? ? ?"num=" + num +
? ? ? ? ? ? ? ? ?", name='" + name + '\'' +
? ? ? ? ? ? ? ? ?", address=" + address +
? ? ? ? ? ? ? ? ?'}';
? ? }
?}
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
while(num-->0){
String color = scanner.next();
int width = scanner.nextInt();
int height = scanner.nextInt();
Prototype prototype = new Prototype(color, width, height);
Prototype clone = prototype.clone();
System.out.println(clone.toString());
}
}
}
class Prototype implements Cloneable{
private String color;
private int width;
private int height;
public Prototype(String color, int width, int height) {
this.color = color;
this.width = width;
this.height = height;
}
@Override
public String toString() {
return "Color: " + color + ", Width: " + width + ", Height: " + height;
}
@Override
protected Prototype clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
}