1、对象的copy(属于浅拷贝)
- 对象的copy有两种方法BeanUtils与PropertyUtils
- 相同的: 都是浅拷贝,都提供了copyProperties()方法,只要
属性名相同
就可以从源bean中拷贝值到目标bean中,而不用管两个对象是不是相同类型的对象 - 不同点: BeanUtils.copyProperties提供类型转换功能,BeanUtils会调用默认的转换器(Converter)进行类型转换,所以在拷贝时能对八个基本类型间进行转换,不能转换时抛出错误
PropertyUtils.copyProperties不提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,会提示argument mistype异常。 - 使用场景:为不同类型的对象而属性却相同的情况下做转换时可以用copy的方法,如果是想要复制一个一模一样的对象建议用对象的clone方法
2、对象的clone方法(有浅拷贝和深拷贝之分)
- 简介:在实际编程过程中,我们常常要遇到这种情况:有一个对象A,在某一时刻A中已经包含了一些有效值,此时可能 会需要一个和A完全相同新对象B,并且此后对B任何改动都不会影响到A中的值,也就是说,A与B是两个独立的对象,但B的初始值是由A对象确定的,这种情况下完全就可以用clone方法而不是copy方法
- 浅克隆和深克隆的主要区别在于:浅拷贝只会拷贝基本类型的值和引用类型对象的地址(而不会给给引用对象也创建一个新的对象),深拷贝不仅会拷贝基本类型的值也会为引用对象创建一个新的对象,然后再把地址指向这个引得引用对象的地址
- 浅克隆
- 1、被复制的类需要实现Clonenable接口
- 重写clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象
class Student implements Cloneable{
private int number;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public Object clone() {
Student stu = null;
try{
stu = (Student)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return stu;
}
}
public class Test {
public static void main(String args[]) {
Student stu1 = new Student();
stu1.setNumber(12345);
Student stu2 = (Student)stu1.clone();
System.out.println("学生1:" + stu1.getNumber());
System.out.println("学生2:" + stu2.getNumber());
stu2.setNumber(54321);
System.out.println("学生1:" + stu1.getNumber());
System.out.println("学生2:" + stu2.getNumber());
}
}
结果:
学生1:12345
学生2:12345
学生1:12345
学生2:54321
- 在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。
- 简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
- 深克隆
- 在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。
- 简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
- 注意:(如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。)
package abc;
class Address implements Cloneable {
//省略get set方法
private String add;
@Override
public Object clone() {
Address addr = null;
try{
addr = (Address)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return addr;
}
}
class Student implements Cloneable{
//省略get set方法
private int number;
//引用类型
private Address addr;
@Override
public Object clone() {
Student stu = null;
try{
stu = (Student)super.clone(); //浅复制
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
stu.addr = (Address)addr.clone(); //深度复制
return stu;
}
}
}