design_model(4)prototype
1.原型模式
使用原型实例复制来创建新的对象。
2.利用Cloneable接口
浅复制
//需要实现Cloneable接口,否则不能克隆
public class PersonTest implements Cloneable {
private ArrayList<String> hobby;
public ArrayList<String> getHobby() {
return hobby;
}
public void setHobby(ArrayList<String> hobby) {
this.hobby = hobby;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class CloneObjectMethodTest {
public static void main(String[] args) throws CloneNotSupportedException {
ArrayList<String> hobby = new ArrayList<>();
hobby.add("lili");
PersonTest person = new PersonTest();
person.setHobby(hobby);
/*浅复制,说明:例如String,Integer等不会出现问题的原因是使用了常量池技术,
* 他们直接指向的是常量池的结果而不是引用,当是其他的对象(未使用常量池的对象)时,
* 那么就指向的是引用,解决的方法将使用的引用对象依次复制
*/
PersonTest clone = (PersonTest)person.clone();
hobby.set(0, "sansan");
System.out.println(person.getHobby().get(0));//sansan
System.out.println(clone.getHobby().get(0));//sansan
}
}
深复制
//需要实现Cloneable接口,否则不能克隆
public class PersonTest implements Cloneable {
private static final String Person = null;
private ArrayList<String> hobby;
public ArrayList<String> getHobby() {
return hobby;
}
public void setHobby(ArrayList<String> hobby) {
this.hobby = hobby;
}
@Override
protected Object clone() throws CloneNotSupportedException {
PersonTest clone = (PersonTest) super.clone();
clone.hobby = (ArrayList<String>) this.hobby.clone();// 深度克隆,将指向的索引都复制一遍
return clone;
}
}
public class CloneObjectMethodTest {
public static void main(String[] args) throws CloneNotSupportedException {
ArrayList<String> hobby = new ArrayList<>();
hobby.add("lili");
PersonTest person = new PersonTest();
person.setHobby(hobby);
PersonTest clone = (PersonTest)person.clone();
hobby.set(0, "sansan");
System.out.println(person.getHobby().get(0));//sansan
System.out.println(clone.getHobby().get(0));//lili
}
}
3.利用序列化和反序列化实现深复制
//需要实现Serializable接口,否则不能序列化和反序列化
public class PersonTest implements Serializable {
private static final String Person = null;
private ArrayList<String> hobby;
public ArrayList<String> getHobby() {
return hobby;
}
public void setHobby(ArrayList<String> hobby) {
this.hobby = hobby;
}
}
public class CloneObjectMethodTest {
//序列化和反序列化实现的是深复制,原因是因为都是从文本中读取的,且反序列化是必须有相应的类已经编译,
//然后在反序列化的过程中产生了新的对象和赋值动作
@SuppressWarnings("resource")
public static void main(String[] args) throws CloneNotSupportedException, FileNotFoundException, IOException {
ArrayList<String> hobby = new ArrayList<>();
hobby.add("lili");
PersonTest person = new PersonTest();
person.setHobby(hobby);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.txt"))) {
oos.writeObject(person);
} catch (Exception e) {
e.printStackTrace();
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.txt"))) {
hobby.set(0, "sansan");
PersonTest rdperson = (PersonTest) ois.readObject();
System.out.println(person.getHobby().get(0));//sansan
System.out.println(rdperson.getHobby().get(0));//lili
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.原型模式效率比较
结论:深复制,cloneable最快,Serializable较慢,new最慢
//New
public void test(TestClone testClone) {
long start = Instant.now().toEpochMilli();
for (int i = 0; i < 9; i++) {
try {
PersonTest1 personTest = new PersonTest1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long end = Instant.now().toEpochMilli();
System.out.println("testNew" + ":" + (end - start));
}
//testClone
public void test(TestClone testClone) {
long start = Instant.now().toEpochMilli();
try {
if (!(testClone instanceof PersonTest2)) {
return ;
}
PersonTest2 personTest = (PersonTest2) testClone;
ArrayList<String> hobby = new ArrayList<>();
personTest.setHobby(hobby);// 1002
for (int i = 0; i < 9; i++) {
Object clone = personTest.clone();
}
} catch (Exception e) {
e.printStackTrace();
}
long end = Instant.now().toEpochMilli();
System.out.println("testClone" + ":" + (end - start));
}
//testSerializable
public void test(TestClone testClone) {
long start = Instant.now().toEpochMilli();
try {
if (!(testClone instanceof PersonTest3)) {
return;
}
PersonTest3 personTest = (PersonTest3) testClone;
for (int i = 0; i < 9; i++) {
PersonTest3 clonePersonTest = PersonTest3.clonePersonTest(personTest);// 1013
}
} catch (Exception e) {
e.printStackTrace();
}
long end = Instant.now().toEpochMilli();
System.out.println("testSerializable" + ":" + (end - start));
}
public static PersonTest3 clonePersonTest(PersonTest3 person) {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.txt"))) {
oos.writeObject(person);
} catch (Exception e) {
e.printStackTrace();
}
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.txt"))) {
PersonTest3 rdperson = (PersonTest3) ois.readObject();
return rdperson;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public class CompareTest implements Runnable {
private TestClone testClone;
public CompareTest(TestClone testClone) {
super();
this.testClone = testClone;
}
@Override
public void run() {
try {
testClone.test(testClone);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
ExecutorService fixPool = null;
try {
fixPool = Executors.newFixedThreadPool(3);
fixPool.submit(new CompareTest((TestClone) new PersonTest1()));// testNew:9004
fixPool.submit(new CompareTest((TestClone) new PersonTest2()));// testClone:0
fixPool.submit(new CompareTest((TestClone) new PersonTest3()));// testSerializable:12
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fixPool != null) {
fixPool.shutdown();
}
}
}
}

浙公网安备 33010602011771号