原型模式:1.当构造函数很复杂的时候使用。
2.clone是native方法,效率比new高。
3.默认克隆是浅克隆,只克隆基础类型,对引用类型不起效果,仍然指向同一个内存地址。
4.深克隆需要重写clone方法,对引用类型也要进行克隆。
/** * 对象 */ public class User implements Cloneable{ private Integer userId; private String userName; private String passWord; private String[] books; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", passWord='" + passWord + '\'' + ", books=" + Arrays.toString(books) + '}'; } @Override protected Object clone() throws CloneNotSupportedException{ User user = (User) super.clone(); //this.books = user.getBooks().clone(); return user; } }
此时为浅克隆。
测试一下:
public class Test { public static void main(String[] args) throws CloneNotSupportedException { User user = new User(); user.setUserId(1); user.setUserName("zhangsan"); user.setPassWord("123456"); user.setBooks(new String[]{"书1","书2"}); User user1 = (User) user.clone(); user1.setUserName("lisi"); String[] books = user1.getBooks(); books[0] = "书3"; user1.setBooks(books); System.out.println(user); System.out.println(user1); } }
分别修改了基本数据类型,和引用数据类型。但实际上引用数据类型的改变把之前的对象属性值也改掉了。
运行结果:
重写克隆方法修改一下:
再次测试: