原型
用于复制已有对象,⚠️和单例相悖
· java的Object中有一个protected native Object clone()用于新建对象空间并复制成员值。在Java中做原型可通过实现标记型接口Cloneable 并重写clone(),但这只是浅克隆:只复制成员值,引用类型则只是复制了引用值。
· 在说单例时提到Java的反序列化可以保证新建对象,除非其声明了Object readResolve()。可以用这个机制达到深克隆的效果。
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.io.*;
abstract class Prototype implements Cloneable, Serializable {
@Override
public Prototype clone() throws CloneNotSupportedException {
return (Prototype) super.clone();
}
public Prototype deepClone() throws IOException, ClassNotFoundException {
try (
ByteArrayOutputStream byteArrOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objOutputStream = new ObjectOutputStream(byteArrOutputStream)
) {
objOutputStream.writeObject(this);
try (
ByteArrayInputStream byteArrInputStream = new ByteArrayInputStream(byteArrOutputStream.toByteArray());
ObjectInputStream objInputStream = new ObjectInputStream(byteArrInputStream);
) {
return (Prototype) objInputStream.readObject();
}
}
}
}
@Getter
@Setter
class TestPrototype extends Prototype {
@Getter
@AllArgsConstructor
static class Inner implements Serializable {
private final int y;
}
private int x;
private Inner inner;
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
TestPrototype prototype1 = new TestPrototype();
prototype1.setX(-1);
prototype1.setInner(new Inner(-2));
TestPrototype prototype2 = (TestPrototype) prototype1.clone();
TestPrototype prototype3 = (TestPrototype) prototype1.deepClone();
System.out.println("浅克隆——基本类型相等:" + (prototype1.getX() == prototype2.getX()));
System.out.println("浅克隆——引用类型相等:" + (prototype1.getInner() == prototype2.getInner()));
System.out.println("深克隆——基本类型相等:" + (prototype1.getX() == prototype3.getX()));
System.out.println("深克隆——引用类型相等:" + (prototype1.getInner() == prototype3.getInner()));
}
}