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();
			}
		}
	}

}
原文地址:https://www.cnblogs.com/gg128/p/9552032.html