一、概念
用一個已經創建的實例作爲原型,通過複製該原型對象來創建一個和原型相同或相似的新對象。在這裏,原型實例指定了要創建的對象的種類。用這種方式創建對象非常高效,根本無須知道對象創建的細節。
二、深拷貝和淺拷貝
淺拷貝:只是新建了一個句柄,句柄指向的內存地址不變
深拷貝:新建句柄,指向的內存地址發生了變化
三、實現
1.淺拷貝
package com.moshi;
public class Test{
public static void main(String[] args) throws CloneNotSupportedException {
User user1 = new User("aa", 12,new Book("一本書"));
User user2 = (User) user1.clone();
user2.setName("bb");
user2.getBook().setBookName("二本書");
System.out.println(user1.getName());
System.out.println(user1.getBook().getBookName());
System.out.println(user1.getBook().hashCode()+"======="+user2.getBook().hashCode());
}
}
class User implements Cloneable{
private String name;
private int age;
private Book book;
public User(String name, int age,Book book) {
super();
this.name = name;
this.age = age;
this.book = book;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Book{
private String bookName;
public Book(String bookName) {
super();
this.bookName = bookName;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
}
輸出結果:aa
二本書
366712642=======366712642
可以發現,兩個對象所依賴的對象的hashcode是同一個對象,引用的內存地址還是同一個。
2.深拷貝
package com.moshi;
public class Test{
public static void main(String[] args) throws CloneNotSupportedException {
User user1 = new User("aa", 12,new Book("一本書"));
User user2 = (User) user1.clone();
user2.setName("bb");
user2.getBook().setBookName("二本書");
System.out.println(user1.getName());
System.out.println(user1.getBook().getBookName());
System.out.println(user1.getBook().hashCode()+"======="+user2.getBook().hashCode());
}
}
class User implements Cloneable{
private String name;
private int age;
private Book book;
public User(String name, int age,Book book) {
super();
this.name = name;
this.age = age;
this.book = book;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
@Override
protected Object clone() throws CloneNotSupportedException {
User user = (User) super.clone();
user.book = (Book) user.getBook().clone();
return user;
}
}
class Book implements Cloneable{
private String bookName;
public Book(String bookName) {
super();
this.bookName = bookName;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
輸出結果:
aa
一本書
366712642=======1829164700
可以發現,重寫clone方法後,兩個對象所依賴的對象的hashCode不一致了。則表示引用的內存地址不一致。
五、原型模式
原型模式便是通過clone方法來創建相同或者相似的類。以此可以提高程序性能。