一、结论
> 我先把**结论**放在前头,在java中,传递的对象如果是基础类型的话,就会直接将值传递过去(深拷贝),传递的对象是需要new的话,就是将对象的地址传递过去(浅拷贝)。
> 这个也困扰了我很久,c语言里还有指针可以区分,而java中就没有指针了,就很难区分了。
二、分析
1.直接上代码
运行的结果:
2.发生这种情况原因是什么呢?
最开始的总结中也提到了,需要new出来的对象才会,这是因为在new这个操作时,需要在jvm的堆中开辟一块空间,(jvm的组成以后有空再写,先埋个坑)开辟完成之后就返回这个对象的地址。
这时候,又有一个问题了,那不需要new的对象,放在哪里呢?
如果是方法内的对象是放在栈里面,如果是.class文件本身就带有的对象,则放在常量池中。
我从别的博客拉了一个图过来,大概是这样子,new出来的对象就是实例。
如果是存储在栈中,就不会存在引用,而是直接使用,换句话说,栈中的值,就是这个方法的本地变量。
3. 关于步骤1中代码的解释
看懂的话就直接跳过这一步了,没看懂的还有点疑惑的可以看一下。
额外提一点
在changeMyClass方法中的MyClass m对象,是存储在这个方法的栈中的,一旦方法结束了,栈就会移除。
三、浅拷贝和深拷贝
1. 浅拷贝
通过new创建出来的对象,一般在传值的时候都是浅拷贝,意思就是**只复制了对象的地址,还是共用同一个对象**。
一般出现在方法传参中,也不需要特地地去实现这个浅拷贝,算是默认的规则。
2. 深拷贝
深拷贝是指能够生成两个一模一样的对象,这**两个对象没有公用同一个地址,而是两个独立存在的对象。
一般的实现方法:可以通过转成JSON格式后,再调用new转成一个对象,这样就可以在堆中创建一个一模一样的对象了。
四、总结
说了那么多,其实就是**传递的是地址还是值的问题**。
引用**C语言中的指针**来做一个总结吧
在C中,是有指针和非指针的对象的,**非指针的对象**,就像**java中的基础数据类型**,**只能传递值**;**指针的对象**,就像**java中new出来的对象**,**传递的是地址**。而C语言需要我们主动的去创建一个对象时给这个对象设定是否是指针类型,也就是要不要加个*,但是在java中,**java将这种需要主动设置的操作改为了默认的一种设定**。
——————————————————————————————
你知道的越多,不知道的越多。
*如果本文有错,可以评论或者私信告诉我。*
**未经允许,不得转载!**