变量之间赋值的传递、方法的参数传递,值传递、引用传递?

关于java程序运行时各种变量在内存的存储知识先看这里》》


变量赋值:

对于基本数据类型变量:即int, short, long, byte, float, double, boolean, char类型的变量。这种类型变量在内存中直接存放数据。变量之间赋值如int a=b;直接传数据。a++,不影响b的数据。

对象变量:对象变量在内存中存放的是引用。这个引用值指向堆中的对象。Object c=b;传的是引用值,他们指向同一个堆对象。

变量之间赋值的传递、方法的参数传递,值传递、引用传递?_第1张图片

如上图,age是int变量,具体数据值如9,就放在那里,而owner是对象变量,它放的是引用,指向堆里owner对象。

下两图是方法调用时在栈帧里的局部变量表里的变量和参数,图示示例了两种引用对象的方式。

(详细java程序运行时的栈帧内存结构看这里》》)


变量之间赋值的传递、方法的参数传递,值传递、引用传递?_第2张图片

此图示例了通过句柄池引用方式指向堆对象的方式

变量之间赋值的传递、方法的参数传递,值传递、引用传递?_第3张图片

此图示例了直接指向堆中对象的方式

两种方式各有优势,第一种方式在对象被GC迁移时只需改变句柄池中的实例指针即可,而不用改变reference引用本身的值。第二种方式就是访问速度快。目前HotSpot虚拟机就采用的第二种方式。

下面用个例子来说明:

下面是个Dog类,用来测试时产生对象,进行引用传递

变量之间赋值的传递、方法的参数传递,值传递、引用传递?_第4张图片
Dog类

mName和mYear是类的实例变量

下面是传递变量测试类,其中也有变量赋值测试然后打印出来

变量之间赋值的传递、方法的参数传递,值传递、引用传递?_第5张图片

主测试类

变量之间赋值的传递、方法的参数传递,值传递、引用传递?_第6张图片

结果:

变量之间赋值的传递、方法的参数传递,值传递、引用传递?_第7张图片

第1行和第2行对比:基础类型变量之间赋值传值,互相不影响;对象变量之间赋值传引用,mainDog和mainDog2指向同一个堆内的对象。mainDog2把对象名字改变后,mainDog打印出来也是改变后的名字。

第2、3、4、5行之间对比:方法参数的传递,基础型参数变量传值,和外面的基础类型实例变量互不影响。方法的对象类型参数传递时传引用,和外面的实例变量引用值相同,指向堆内同一个对象。此时堆内只有一个dog。

第5、6、7行之间对比:方法内的对象参数或对象局部变量改变引用值时,不影响外面的对象实例变量。此时方法内mainDog对象参数变量指向的堆对象和实例对象变量mainDog指向的堆对象不同。堆内曾有过2个dog。

如何 让对象变量之间赋值传值而不是引用呢?

Dog dog=new dog();

Dog dog2=dog;

如要达到dog2是个独立的堆对象,但属性要与dog一模一样;

Dog dog2=dog.clone();需要类实现clone接口;

设计模式中有个原型模式,就是clone;原型模式

你可能感兴趣的:(变量之间赋值的传递、方法的参数传递,值传递、引用传递?)