浅复制和深复制

时间:2022-02-05 03:57:59
public class test {
public static void main(String[] args) {
A c1=new A(1);
A c2;
A c3;
c3=new A(3);
c3.right=new A(4);
c3.left=new A(5);
c1.left=c3;
c2=c1;
c1=c1.left;
System.out.println(c2.num);
}
}
class A{
int num;
A left;
A right;
A(int a){
num=a;
}
}


其中这段
		
c2=c1;
c1=c1.left;

为什么c2没有跟着变成c1.left   ????
c2=c1;这句不应该是浅复制吗?
c2的值应该跟着c1变化才对啊!

4 个解决方案

#1


因为JAVA是值传递的。
c2=c1; //c1其实是一个地址,比如0x10,这个地址的堆空间中的实例是new出来的A(1),此时c2=0x10
c1=c1.left  //c1保存的地址变化了,不会影响到c2

记住呀,是值传递的!值传递的!值传递的!
重要的话说三遍。

#2


引用 1 楼 qq_21255915 的回复:
因为JAVA是值传递的。
c2=c1; //c1其实是一个地址,比如0x10,这个地址的堆空间中的实例是new出来的A(1),此时c2=0x10
c1=c1.left  //c1保存的地址变化了,不会影响到c2

记住呀,是值传递的!值传递的!值传递的!
重要的话说三遍。

既然是值传递的,为什么说c2=c1 是把c1 的地址赋给了c2。

#3


c1存的是实例在堆中的地址,在赋值的时候c1就是把这个地址复制了一份给c2了。并不是把c1的地址传给了c2。就像
int c1=1,c2=c1;
c1=3;
此时c2=1,这就是值传递。。

#4


引用 3 楼 qq_21255915 的回复:
c1存的是实例在堆中的地址,在赋值的时候c1就是把这个地址复制了一份给c2了。并不是把c1的地址传给了c2。就像
int c1=1,c2=c1;
c1=3;
此时c2=1,这就是值传递。。

画了张图基本上已经理解了,但是你说的值传递的概念应该是指函数传参时候的吧!?
这里面就是类的引用变量之间的切换。
另外让人困惑的就是这个A类到底有多大,占多少字节。A类其实是个二叉树模型,是不是顶层的占了最大的空间,最底层的只有一个int字节数,left和right都是null

#1


因为JAVA是值传递的。
c2=c1; //c1其实是一个地址,比如0x10,这个地址的堆空间中的实例是new出来的A(1),此时c2=0x10
c1=c1.left  //c1保存的地址变化了,不会影响到c2

记住呀,是值传递的!值传递的!值传递的!
重要的话说三遍。

#2


引用 1 楼 qq_21255915 的回复:
因为JAVA是值传递的。
c2=c1; //c1其实是一个地址,比如0x10,这个地址的堆空间中的实例是new出来的A(1),此时c2=0x10
c1=c1.left  //c1保存的地址变化了,不会影响到c2

记住呀,是值传递的!值传递的!值传递的!
重要的话说三遍。

既然是值传递的,为什么说c2=c1 是把c1 的地址赋给了c2。

#3


c1存的是实例在堆中的地址,在赋值的时候c1就是把这个地址复制了一份给c2了。并不是把c1的地址传给了c2。就像
int c1=1,c2=c1;
c1=3;
此时c2=1,这就是值传递。。

#4


引用 3 楼 qq_21255915 的回复:
c1存的是实例在堆中的地址,在赋值的时候c1就是把这个地址复制了一份给c2了。并不是把c1的地址传给了c2。就像
int c1=1,c2=c1;
c1=3;
此时c2=1,这就是值传递。。

画了张图基本上已经理解了,但是你说的值传递的概念应该是指函数传参时候的吧!?
这里面就是类的引用变量之间的切换。
另外让人困惑的就是这个A类到底有多大,占多少字节。A类其实是个二叉树模型,是不是顶层的占了最大的空间,最底层的只有一个int字节数,left和right都是null