原創:轉載需註明原創地址 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; } }
結束🔚