Java學習筆記之深入理解引用
引言:Java中數據傳遞的方式,除了基本數據類型是按照值傳遞,其它類型全部是按照引用傳遞,這和C++有很大區別,但是很多網上文章都解釋的不清楚,甚至是錯誤的,在查閱資料之后,下面整理出一個比較容易理解的版本。
我們知道引用根據引用的類型不同有許多名稱,如字符串引用,數組引用等等。
一、棧內存和堆內存
我們用數組來引出和解釋這兩個概念。
數組引用變量只是一個引用,這個引用可以指向任何有效的內存。
簡單的理解就是,這個引用是用來存放數據地址的(數據地址指向數據在內存中的存儲位置),在聲明引用變量的時候,只是預留了一段空間來存儲地址,但是還沒有真正賦給這個引用變量一個地址,你賦給它哪個數據的地址,這個引用就指向這個地址(所以上面說“這個引用可以指向任何有效的內存”),那么你就可以通過這個引用訪問該數據了。
如String[] p = new String(5);
p就是一個數組引用變量,這個數組含有5個元素。但是,實際數組元素被存儲在堆(heap)中,而數組引用變量是被存在棧(stack)內存中,如下圖:
也就是說,數組在內存中的存儲實際是分別存儲在兩種不同性質的內存中:棧內存和堆內存。實際上,在Java中其它引用變量也是如此。
二、類的引用
考慮下面的自己建立的一個簡單類:
class Test { private int a; Test() { a = 0; } public void set(int b) { a = b; } public void showInfo() { System.out.println("The value of a is :" + a); } } |
假如我們有如下語句:
Test m = new Test()
我們常??吹接羞@樣的說法:m是一個對Test類的引用變量,感覺好難理解,怎么實例化一個類就成了引用呢?讓我們一步一步來看這個實例化過程。
我們把上面語句拆開成下面語句:
Test m;
m = new Test();
我們知道,Java中除了內置基本類型,其他類型全部是引用,Test當然不是內置基本類型,所以Test m 就是建立了一個指向Test類的引用:
Test m是聲明了一個Test類的引用變量m,就是告訴編譯器要預留一部分棧內存給m,我會用m來存儲一個地址指向存儲有Test類對象存儲單元,注意這個Test類對象和上面講的數組元素一樣,是存儲在堆內存中的。但Test m也只是聲明而已,但是指向哪一個Test類對象,目前還不知道,因為我們還沒有賦給它一個Test 類對象的地址,它怎么可能知道指向哪兒?
m = new Test() 就是來給m指明方向的,new Test()構造了一個Test類對象,系統會給這個對象分配一定的內存空間留給這個對象存儲自己的數據,通過運算m = new Test(),把這個新建的Test類對象在內存(堆內存)中的地址賦給m,于是m就知道它應該指向哪兒了:
總結出以下幾點:
Java除了內置基本數據類型(int , double ,float等等)是值傳遞,其他類型的都是引用
聲明一個類型的引用時,只是為引用變量預留了一個存儲地址空間,該引用變量可以指向任何有效的內存單元
Java大量使用引用的方式可以減少值傳遞過程中復制數據的開銷,提高效率。

0
posted on 2014-10-17 12:53 順其自然EVO 閱讀(292) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄