浅拷贝,使用setter方法修改了基本数据类型的内存地址
来源:9-2 原型模式coding
AndrewLu
2020-12-16
在需要拷贝的类中声明了个int类型的变量(考虑到Integer类型是被final修饰默认创建新的对象),从结果中看出clone方法默认为浅拷贝,但是我发现通过age的setter方法修改值后,stu1和stu3(拷贝)的age内存地址不一样了,所以我很困惑基本数据类型的setter方法还会修改内存地址吗???
public class CopyTest {
public static void main(String []args) throws CloneNotSupportedException {
Student stu1 = new Student("Andrew",23);
//把stu1拷贝给stu3
Student stu3 = (Student) stu1.clone();
//比较拷贝完后的stu1和stu3中的age地址: 输出true,表示stu3为浅拷贝
System.out.println(stu1.getAge()== stu3.getAge());
//修改stu1的age值
stu1.setAge(24);
//比较原对象和拷贝对象的age值和地址,如果是浅拷贝那么里面的属性是共享同一个内存地址,那么修改stu1之后stu2会随之改变
//输出24,改变了
System.out.println("stu1:"+stu1.getAge());
//输出23,没变,??
System.out.println("stu3:"+stu3.getAge());
//输出false,表明不是一个内存地址,??
System.out.println("比较age地址:"+(stu3.getAge()==stu1.getAge()));
}
}
class Student implements Cloneable{
private String name;
private int age;
Student(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
//没有改写,使用默认的clone方法
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
写回答
1回答
-
你上面也说了,你用的是基本数据类型int,所以不存在对象引用,这些基本类型数据是存在运行时常量池的,并不是通过new来的,所以你修改基本数据类型,都是深拷贝,深、浅拷贝,只是针对引用类型对象。比如new Object(),new Date()这些是存在堆内存(heap)中。这里涉及到jvm的内存分配知识,个人理解,有不正确的还望各位大佬更正。再补充一张内存模型图,基本数据类型就是存在方法区里面的运行时常量池中,也称作“非堆”,
112020-12-16
相似问题