原创:转载需注明原创地址 http://www.javashuo.com/article/p-uxpbfpbb-ex.html
下面经过一段代码和debug结果来展现Java中=操做的赋值改变过程。Test实体类会在最后贴出。html
Test test1 = new Test(); test1.setKey(1); test1.setValue(1); Test test4 = new Test(); test4.setKey(4); test4.setValue(4); Test test2 = test1; test2.setIndex(2); test2 = test4; test2.setIndex(4);
结果:java
能够看出:Java的=操做符会将=右侧对象实例的地址引用赋值给=左侧的对象实例,在被赋值期间,值的改变是怎样的呢?测试
继续看: this
能够看到test1的index值是改变了的,test4的index值也是改变了的,test2首先是test1的引用,在引用test1的时候改变test2的值,test1的值也会相应改变,说明在引用期间全部的改变都是针对实际内存地址操做的,而不是单纯针对该对象的值进行改变。spa
接下来,咱们再看一下方法传递时候的引用是怎么改变的:debug
先贴上两个传入test参数而且在方法内尝试改变index值的方法:3d
/** * 尝试直接改变test的index值 * @param test */ public static void tryInChangeIndex(Test test){ test.setIndex(123); } /** * 尝试间接改变test的index值 * @param test */ public static void tryLinkChangeIndex(Test test){ Test testLink = new Test(); testLink = test; testLink.setIndex(456); }
结果:code
毫无疑问,成功改变test1的值。htm
再看下一个方法:对象
一样能够改变,没有问题。
再看看String传递是怎么回事;
先贴尝试改变String的两个方法:
/** * 尝试改变string的值 * @param str */ public static void tryChangeString(String str){ str = "hello new str value"; } /** * 尝试改变string的值方法2 * @param str */ public static void tryChangeStringTwo(String str){ String newStr = str; newStr = "world in this place"; }
String str1 = "good nice"; String str2 = "i'm iron man"; tryChangeString(str1); tryChangeStringTwo(str2);
debug结果:
从这里能够看出,方法里面的str值是有改变的,可是方法外str1的值依然是“good nice”,这说明传入的String 类型是不能被改变的。
继续看下面这个方法:
一样的,在方法里面,虽然把str指向了newStr,而且给newStr赋了新的值,可是str的值依然是没有变化的,咱们再看一下str2的值:
str2的值也是没有被改变。
我猜想: 这是由于参数方法在参数列表这里的String str 从新建立了一个实例,并且将该实例的内存引用地址指向了str2的内存引用地址,因此值会相等,可是当对str进行赋值操做的时候,会从新new String,也就是从新开辟一块内存空间去存放这个新的值,而且str会指向这块内存地址,因此改变str的值是没法改变str2的值的,由于它俩根本就不是同一个实例,只是指向了相同的内存引用地址而已.
*** String 是final类,不可被继承, 可是String若是实例化的时候没有定义为final变量,仍是能够从新赋值的!编译器不会报错!注意区别 final类和final变量.
再来看一种状况:
TestFather father = new TestFather(); Test son = new Test(); son.setIndex(123456); father.setSon(son); son.setIndex(789);
这种状况下,father里面的son值会怎么变化?debug看一下
到了72行,72行还没执行的以后,father的son的index值仍是123456的,再往下走一步:
BOOM!!! Every thing is diffrent
很明显,son变了,father拥有的只是son的一个引用,拥有了son的身体却没有son的灵魂,这里涉及到一个深拷贝和浅拷贝的问题,有兴趣能够自行Google或者Baidu。
Test.java文件
package entity; /** * 测试实体类 */ public class Test { private int key; private int value; private int index; //getter setter 省略 }
TestFather.java
package entity; /** * Test的father */ public class TestFather { private int num; private Test son; public int getNum() { return num; } public void setNum(int num) { this.num = num; } public Test getSon() { return son; } public void setSon(Test son) { this.son = son; } }
结束🔚