Java对象的访问定位
????這篇博文主要介紹Java 對象的引用方式,以及對于Java 程序設計語言中關于”引用傳遞”與”值傳遞”問題談一談看法。
Java對象的訪問定位
????我們知道Java 程序需要通過棧上的引用(reference) 數據來操作堆上的具體對象。由于reference 類型在Java 虛擬機規范中只規定了一個指向對象的引用,并沒有定義這個引用通過何種方式去定位、訪問堆中對象的具體位置,所以對象的訪問方式也是取決于虛擬機而定的。但是主流的訪問方式有句柄和直接指針兩種。下面一一分作介紹。
句柄訪問
????使用句柄方式訪問的話,在Java 堆中將會劃分出一塊內存來作為句柄池,reference 中存儲的就是對象的句柄地址,而句柄中包含了對象實例數據與類型數據各自的具體地址信息。如圖:
直接指針
????如果使用直接指針訪問,那么Java 堆中對象的布局就必須考慮如何放置訪問類型數據的想關信息,而reference 中存儲的直接就是對象的地址。如圖:
兩種方式的對比:
????使用句柄的最大好處就是reference 中存儲的是穩定的句柄地址,在對象移動(在垃圾回收時往往存在大量的對象移動)時只會改變句柄中的實例數據指針,而reference 本身不需要修改。
????使用直接指針的最大好處時速度更快,它節省了一次指針定位的開銷,由于對象的訪問在Java 中非常普遍,因此這類開銷積少成多后也是一項非常可觀的執行成本。就Sun HotSpot 虛擬機而言,它是使用第二種方式進行對象訪問的。
下面就來談一談Java 中關于“引用傳遞”與“值傳遞”的問題:
在探討這個問題之前我們先了解一下什么是值傳遞什么是引用傳遞(來自百度百科):
????引用傳遞:所謂引用傳遞是指在調用函數時將實際參數的地址傳遞到函數中,那么在函數中對參數所進行的修改,將影響到實際參數。
????值傳遞:值傳遞是在程序設計中,對于函數調用的一種方法,值引用只是把值傳遞到新的變量,修改新的變量,不會修改原來的參數。
????通過上面關于Java 對象的兩種訪問方式我們知道,在虛擬機棧中通過對象的引用來操作堆上的具體對象。下面來看兩段代碼:
@Testpublic void test1(){int i = 5;change1(i);System.out.print(i);}public void change1(int i){i = 10;}我想大多數Java 程序員都是到輸出的結果是5,還有下面一段代碼:
@Testpublic void test2(){Demo demo = new Demo();System.out.println(demo.num);change2(demo);System.out.println(demo.num);}public void change2(Demo demo){demo.num = 10;}class Demo{public int num = 5;}輸出結果為:
5
10
上面兩個例子分別測試了基本數據類型與引用數據類型,現在就上面出現的結果做一些理論上的分析:
????基本數據類型的傳遞:基本數據類型的值就保存在變量中,傳遞的是基本類型的字面量值的拷貝,當發生傳遞時并不會改變原來的變量值。
????引用數據類型的傳遞:變量中保存的是實際對象的地址,傳遞的是堆中對象的一個拷貝(也就是引用),操作的并不是堆中的對象本身,在數據傳遞時原來的引用地址會被覆蓋,賦值運算會改變原來引用中保存的地址,但是堆中的對象本身不會被改變。
總結:
????“Java 所支持的‘按址傳遞’傳遞是完全錯誤的”,因為Java 對象標志符實際上是“符號引用”。也許有人會贊成這種精確卻令人費解的解釋,但我認為我的這種方法可以簡化概念上的理解并且不會傷害到任何事物。(好了,那些言語專家可能會說我在說謊,但是我認為我只是提供了一個合適的抽象罷了。
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????->《Java編程思想》
????????????????????????????????????????????????????????????????????????????????????????????????????????參考資料:《深入理解Java 虛擬機》周志明 著
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????《Java 編程思想》Bruce Eckel 著
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????? 知乎平臺->手動@ Intopass、祖春雷
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????? 百度百科
總結
以上是生活随笔為你收集整理的Java对象的访问定位的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑网卡怎么改动 电脑网卡修改方法
- 下一篇: Java 多态之“绑定”