学习原型模式
1、什么是原型模式
原型模式主要是指复制对象的方式来创建对象,这样的优点是要比new对象的方式快
2、实现原型模式
1、浅度克隆:主要是调用java提供的Cloneable中的clone方法进行复制对象,调用方法较为简单,以下我们来实现下代码
package protoType;
//Cloneable 告诉虚拟机 这个对象是可以克隆的
public class User implements Cloneable{
private Long id;
private String name;
private String[] arr; //浅度克隆不会复制
public String[] getArr() {
return arr;
}
public void setArr(String[] arr) {
this.arr = arr;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 实现克隆的方法
* 如果只是添加clone则为浅度克隆
*/
@Override
protected User clone() throws CloneNotSupportedException {
return (User)super.clone();
}
}
2、此时,一个实现了Cloneable接口的User对象已经创建,下面我们来调用一下,调用时对比了每次 等于号(=)复制和复制对象的区别
public static void main(String[] args) throws CloneNotSupportedException {
User user = new User();
user.setId(1L);
user.setName("张三");
String arr[] = {"1","2"};
user.setArr(arr);
//如何实现克隆 如果是之前的想法,应该是 直接赋值的方式,此时发现对象地址一致,如果此时修改了user2里面的name,则user对象也会改变
User user2 = user;
user2.setName("李四");
//原对象
System.out.println(user);// 地址
System.out.println(user.getId());//参数
System.out.println(user.getName());//参数
System.out.println(user.getArr());//参数
//赋值对象
System.out.println(user2);// 地址
System.out.println(user2.getId());//参数
System.out.println(user2.getName());//参数
System.out.println(user2.getArr());//参数
/**
* 实现克隆
* 1 实现Cloneable接口
* 2 实现clone接口方法
* 此时会发现地址不同,也就是在堆中重新复制了一个新的对象
* */
User user3 = user.clone();
//赋值对象
System.out.println(user3);// 地址
System.out.println(user3.getId());//参数
System.out.println(user3.getName());//参数
System.out.println(user3.getArr());//参数
}
3、深度克隆:如果一个对象中引用了其他对象的情况,那么Cloneable接口只会复制当前对象,内对象不会进行复制,还是原来的地址,例如User对象中的arr数组,没有深度克隆前,user克隆后还是原地址,此时,我们需要通过深度克隆的方式来创建对象 ,其实深度克隆就是将原有对象中的参数new一个新的加入到新对象中,此时user复制后arr也变成了新的地址
@Override
protected User clone() throws CloneNotSupportedException {
User user = (User) super.clone();
String[] _arr = new String[user.getArr().length];
for(Integer i = 0;i<user.arr.length;i++){
_arr[i] = user.arr[i];
}
user.setArr(_arr);
return user;
}