關於Java的=賦值操做和方法傳遞對象時的引用

  

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

 

  結束🔚

相關文章
相關標籤/搜索