一、内存
Java是在JVM所虚拟出的内存环境中运行的。内存分为栈(stack)和堆(heap)两部分。
栈 &堆
在Java中,JVM中的栈记录了线程的方法调用。每个线程拥有一个栈。在某个线程的运行过程中,如果有新的方法调用,那么该线程对应的栈就会增加一个存储单元,即帧(frame)。在frame中,保存有该方法调用的参数、局部变量和返回地址。
Java的参数和局部变量只能是基本类型的变量(比如int),或者对象的引用(reference)。因此,在栈中,只保存有基本类型的变量和对象引用。
引用所指向的对象保存在堆中。(引用可能为Null值,即不指向任何对象)
当被调用方法运行结束时,该方法对应的帧将被删除,参数和局部变量所占据的空间也随之释放。线程回到原方法,继续执行。当所有的栈都清空时,程序也随之运行结束。
二、拷贝
拷贝发生的场景
1.赋值
2.参数传递
3.拷贝函数
4.拷贝构造函数
深拷贝 浅拷贝
浅拷贝:仅拷贝对象本身(对象包含的基本变量和对象包含的引用),而不拷贝对象包含的引用
所指向的对象。
深拷贝:不仅拷贝对象本身,还拷贝对象包含的引用指向的所有对象。(若不对clone()方法进行改写,默认浅拷贝)
赋值/参数传递 默认情况
在Java/Python中数据是按值传递的: 赋值=和拷贝copy()不同
基本数据类型:数值
对象:对象即对象引用
(因此赋值和参数传递对象时,对象所指向的实体是一样的,对象的地址是一样的)
C++中:
基本数据:数值
对象:对象的赋值调用拷贝函数(特殊的创建对象是,用另一个对象对创建对象初始化时,调用拷贝构造函数 参数传递采用拷贝构造函数。
<因此,仅用到对象的数值而不对对象进行修改时,参数传递一般直接传递对象的引用,并且通常用const限定使得函数不会改变对象的状态>
clone()方法默认情况
默认为浅拷贝,若要实现深拷贝需要重写拷贝函数。
Java的clone()方法
⑴clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
①对任何的对象x,都有x.clone() !=x//克隆对象与原对象不是同一个对象
②对任何的对象x,都有x.clone().getClass()= =x.getClass()//克隆对象与原对象的类型一样
③如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。
(==判断地址是否相同 equals()判断内容是否相同)
序列化实现深拷贝
Java Seriazable
拷贝函数和拷贝构造函数
(c++)拷贝函数 : 非初始化时的对象赋值 需要改变的话需重载等号
(c++)拷贝构造函数通常用于: 需要改变的话需重载拷贝构造函数
1.通过使用另一个同类型的对象来初始化新创建的对象。
2.复制对象把它作为参数传递给函数。
3.复制对象,并从函数返回这个对象。
如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数
https://wizardforcel.gitbooks.io/w3school-cpp/content/Text/55.html