对象克隆
把A对象的属性值完全拷贝给B对象,也叫对象拷贝,对象复制
浅克隆(浅拷贝):
仅拷贝基本类型和引用,堆内的引用对象和被拷贝的对象共享。
基本数据类型拷贝过来的是具体的数据,引用数据类型拷贝过来的是地址值。
Object类默认的是浅克隆
深克隆(深拷贝):
完全拷贝一个对象,包括基本类型和引用类型,堆内的引用对象也会复制一份。
基本数据类型拷贝过来,字符串复用,引用数据类型会重新创建新的
因此深拷贝是安全的,浅拷贝的话如果有引用对象则原先和拷贝对象修改引用对象的值会相互影响。
代码实现:
public class Demo {
public static void main(String[] args) throws CloneNotSupportedException {
// protected object clone(int a) 对象克隆
//1.先创建一个对象
int[] data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
User u1 = new User(1, "zhangsan", "1234qwer", "girl11", data);
//2.克隆对象
//细节:
//方法在底层会帮我们创建一个对象,并把原对象中的数据拷贝过去。
//书写细节:
//1.重写Object中的clone方法
//2.让javabean类实现Cloneable接口
//3.创建原对象并调用clone就可以了
User u2 =(User)u1.clone();
//验证一件事情:Object中的克隆是浅克隆
//想要进行深克隆,就需要重写clone方法并修改里面的方法体
int[] arr = u1.getData();
arr[0] = 100;
System.out.println(u1);
System.out.println(u2);
}
}
//Cloneable
//如果一个接口里面没有抽象方法
//表示当前的接口是一个标记性接口
//现在Cloneable表示一旦实现了,那么当前类的对象就可以被克降
//如果没有实现,当前类的对象就不能克隆
public class User implements Cloneable {
private int id;
private String username;
private String password;
private String path;
private int[] data;
// 无参构造方法和有参构造方法以及get和set方法,toString略
//重写clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
//调用父类中的clone方法
//相当于让Java帮我们克隆一个对象,并把克隆之后的对象返回出去。
//先把被克隆对象中的数组获取出来
int[] data = this.data;
//创建新的数组
int[] newData =new int[data.length];
//拷贝数组中的数据
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
//调用父类中的方法克隆对象
//强转是因为创建了一个新的Object对象来复制u1中的属性,然后再强转成User赋给u2
User u=(User)super.clone();
//因为父类中的克隆方法是浅克隆,替换克隆出来对象中的数组地址值
u.data =newData;
return u;
}
}
对象的属性拷贝BeanUtils
简介
BeanUtils提供对Java反射和自省API的包装。其主要目的是利用反射机制对JavaBean的属性进行处理。这个过程是基于属性名称的匹配,并且是浅拷贝(shallow copy)
Spring 的 BeanUtils 类位于 org.springframework.beans
包中
使用场景
当我们如果有两个具有很多相同属性的JavaBean,User1Bean,User2Bean,我想吧User1Bean的属性全部赋值给User2Bean。
传统方式赋值:
user2Bean.setName(user1Bean.getName());
…3个属性,set,get 3次,但要是10000个属性会变得很麻烦
所以改进赋值方式
BeanUtils
// 使用示例
BeanUtils.copyProperties(targetObj, srcObj);
/*targetObj:被赋值的目标对象
srcObj : 具备数据的对象*/
注意事项:
-
srcObj中的存在的属性,targetObj中一定要有,但是targetObj中可以有多余的属性;
-
targetObj中与srcObj中相同的属性都会被替换,不管是否有值;
-
targetObj、 srcObj中的属性要名字相同,才能被赋值,不然的话需要手动赋值;
-
Spring的BeanUtils的CopyProperties方法需要对应的属性有getter和setter方法;
-
Spring 的 BeanUtils 提供的功能比 Apache Commons BeanUtils 少,但通常性能更好,因为它不依赖于反射。
-
Spring 的 BeanUtils 主要用于属性复制,而 Apache Commons BeanUtils 提供了更多的工具方法。
-
Spring 的 BeanUtils 主要用于简单的属性复制。对于更复杂的对象映射需求,你可能需要考虑使用专门的对象映射工具,如 MapStruct 或 ModelMapper。