场景

在实际编程中需要两个相互独立的对象A,B,对象B的初始数据和A一致。改变对象B不会影响对象A。

错误用法

User user1 = new User();
user1.setAge(18);
User user2 = new User();
user2 = user1;
user2.setAge(19);
System.out.println("user1.age="+user1.getAge());
System.out.println("user2.age="+user2.getAge());

从结果看,改变stu2,stu1也改变了。(stu2 = stu1)的作用是将stu1的引用赋值给stu2,这样,stu1和stu2指向内存堆中同一个对象。

该方法仅适用于值类型,对于引用类型就会出现改变一个对象,另一个也改变。
值类型:四类八种
1,整型3种 byte,short,int,long
2,浮点型2种 float,double
3,字符型1种 char
4,逻辑型1种 boolean

引用类型:(数组,类,接口)
String,Integer也是引用类型,是类。String可以直接赋值,而两个对象不相互影响是因为String是不可变类型。
即值不可改变,可以改变指向,直接赋值就是重开辟一个地址,将新值保存。所以直接复制后,两个对象相互不影响。

通过set方法,将A对象值赋给B对象

User.java

@Data
public class User{
    private String name;
    private String sex;
    @Max(value=10,message = "年龄不能超过10岁。")
    private int age;
}

调用方法

Student stu1 = new Student();
stu1.setAge(18);
Student stu2 = new Student();
stu2.setAge(stu1.getAge());
stu2.setAge(19);
System.out.println("学生1="+stu1.getAge());   --18 
System.out.println("学生2="+stu2.getAge());   --19   

缺点:对象属性较多时比较麻烦

重写java.lang.Object类中的方法clone()

浅克隆:不支持引用类型复制(子对象不复制)

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。

1.被复制的类需要实现Clonenable接口
2.覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。

User.java: 要复制的对象类中重写clone方法

@Data
public class User implements Cloneable{
    private String name;
    private String sex;
    @Max(value=10,message = "年龄不能超过10岁。")
    private int age;

    @Override
    public  Object clone(){
        User user = null;
        try{
            user = (User)super.clone();
        }catch (CloneNotSupportedException e){
            System.out.println(e.getMessage());
        }
        return user;
    }
}

调用方法:

User user1 = new User();
user1.setAge(18);
User user2 = (User)user1.clone();
user2.setAge(19);
System.out.println("user1.age="+user1.getAge());
System.out.println("user2.age="+user2.getAge());
深克隆:支持引用类型复制

User.java 类中追加Address类型的变量

@Data
public class User implements Cloneable{
    private String name;
    private String sex;
    @Max(value=10,message = "年龄不能超过10岁。")
    private int age;

    private Address address;


    @Override
    public  Object clone(){
        User user = null;
        try{
            user = (User)super.clone();
        }catch (CloneNotSupportedException e){
            System.out.println(e.getMessage());
        }
        return user;
    }
}

Address.java

@Data
public class Address {
    private String address;
}

调用方法:

Address a = new Address();
a.setAddress("山东");
User user1 = new User();
user1.setAddress(a);
User user2 = (User)user1.clone();
a.setAddress("上海");
System.out.println("user1.address="+user1.getAddress());--上海
System.out.println("user2.address="+user2.getAddress());--上海

此时,子对象并未被真正复制。想要真正复制,需要将子类的clone的方法也重写。
Address.java

@Data
public class Address implements Cloneable{
    private String address;
    @Override
    public  Object clone(){
        Address address = null;
        try{
            address = (Address)super.clone();
        }catch (CloneNotSupportedException e){
            System.out.println(e.getMessage());
        }
        return address;
    }
}

User.java

@Data
public class User implements Cloneable{
    private String name;
    private String sex;
    @Max(value=10,message = "年龄不能超过10岁。")
    private int age;

    private Address address;


    @Override
    public  Object clone(){
        User user = null;
        try{
            user = (User)super.clone();
        }catch (CloneNotSupportedException e){
            System.out.println(e.getMessage());
        }
        user.address = (Address)address.clone();
        return user;
    }
}

调用方法:

Address a = new Address();
a.setAddress("山东");
User user1 = new User();
user1.setAddress(a);
User user2 = (User)user1.clone();
a.setAddress("上海");
user2.setAddress(a);
System.out.println("user1.address="+user1.getAddress());--上海
System.out.println("user2.address="+user2.getAddress());--山东

工具类BeanUtils:浅拷贝

BeanUtils.copyProperties(元对象,目标对象);
User.java

@Data
public class User{
    private String name;
    private String sex;
    @Max(value=10,message = "年龄不能超过10岁。")
    private int age;

    private Address address;
}

Address.java

@Data
public class Address{
    private String address;
}

调用方法

@Test
	public void stuCopyTest(){
		Address a = new Address();
		a.setAddress("山东");
		User user1 = new User();
		user1.setAddress(a);
		user1.setAge(18);
		User user2 = new User();
		BeanUtils.copyProperties(user1,user2);
		a.setAddress("上海");
		user2.setAge(19);
		System.out.println("user1.age="+user1.getAge()+"user1.address="+user1.getAddress());
		System.out.println("user2.age="+user2.getAge()+"user2.address="+user2.getAddress());
	}

返回结果:子对象没有实现完全copy
user1.age=18,user1.address=Address(address=上海)
user2.age=19,user2.address=Address(address=上海)

posted on 2022-10-09 15:57  飞飞乐园  阅读(3940)  评论(0编辑  收藏  举报