Java值傳遞與引用傳遞深度解析

眾所周知,Java存在8種基礎數(shù)據(jù)類型。
不過,Java字節(jié)碼中還有額外的兩種基礎數(shù)據(jù)類型,分別是reference type與returnAddress type。

想要學習Java 中的參數(shù)傳遞,就必須理解JVM是如何解釋基礎數(shù)據(jù)類型與引用數(shù)據(jù)類型的。

一切皆數(shù)據(jù)?一切皆對象?

我們先從最基礎的賦值開始:

Object A = new Object();

new Object() 做了什么?

JVM將在GC堆中開辟一定大小的空間用以存放此Object,此Object是引用數(shù)據(jù)類型(注意不是reference類型)。

Object A 做了什么?

JVM將在虛擬機棧中此線程棧開辟出一個slot用以存放A,注意此處A為reference type。(slot可以理解為用以存放基礎數(shù)據(jù)類型的線程私有的空間)

“ = ” 做了什么?

reference type 的A被賦值為先前new Object() 指令所產(chǎn)生的引用數(shù)據(jù)類型的一個對象。

案例分析

static String s1 = "abc" ;

public static void changeString(String s2){

s2="bcd";

}

changeString(s1);

運行以上代碼,s1改變了嗎?

答案是沒有。

為什么呢?

因為JVM中傳遞的不是reference本身,而是reference的拷貝。

或者你可以理解為傳遞的是一個int類型的數(shù)據(jù),不過這個int類型比較特殊,里面存放有一個對象的地址。

我們來一步一步分析上面的代碼:

String s1 = "abc";
//JVM開辟了一定大小的空間用以存放一個String對象,我們假設這個空間的起始值為0x8000。那么reference類型的s1就被賦值為0x8000。

void changeString(String s2){
//JVM中傳遞的是基礎數(shù)據(jù)類型reference ,此時開辟一個線程幀,為s2開辟一個slot,其值與s1相同,為0x8000

s2="bcd"; 
// 我們假設“bcd”的地址為0x9000,那么s2作為一個reference類型的數(shù)據(jù)將被賦值為0x9000

}

所以,函數(shù)changeString() 所做的只是新建了一個reference類型的數(shù)據(jù)s2,然后把“bcd”的地址賦值給了s2,對于s1和s1所指向的對象“abc”沒有做任何事,我們當然也看不到任何改變了。

綜上所述,JVM中傳遞的所有數(shù)據(jù)都是基礎數(shù)據(jù)類型的數(shù)據(jù),只是JVM會解析這是一個普通的數(shù)據(jù)類型還是 reference type 或 returnAddress type 。

所以,所有對形如s2這樣的傳入reference進行 = 的賦值,都不會改變s1的數(shù)據(jù),即s1依然會指向原來的對象。

用不太嚴謹?shù)脑拋碚f:Java中傳遞引用數(shù)據(jù)類型本質(zhì)是傳遞其地址的拷貝。

所以,才說Java中只有值傳遞。

不過,值傳遞與引用傳遞并不能完全區(qū)分來看,將引用數(shù)據(jù)類型看做是傳遞引用對于理解Java、日常編程并無不可。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,697評論 18 399
  • 集合框架: 1)特點:存儲對象;長度可變;存儲對象的類型可不同2)Collection(1)List:有序的;元素...
    Demo_Yang閱讀 1,386評論 0 4
  • 1. 面向?qū)ο蟮奶卣饔心男┓矫妫?抽象:抽象是將一類對象的共同特征總結出來構造類的過程,包括數(shù)據(jù)抽象和行為抽象兩方...
    程序熊大閱讀 4,547評論 6 74
  • 1、.java源文件: 一個以”.java“為后綴的源文件:只能有一個與文件名相同的類,可以包含其他類。 2、類方...
    Hughman閱讀 1,744評論 1 9
  • 朗讀者第四期,倪萍朗讀了她寫的姥姥語錄。 天黑了就是遇上擋不住的大難了,你就得認命。人命不是撂下(放棄),是咬著牙...
    橙心綠思閱讀 454評論 0 2

友情鏈接更多精彩內(nèi)容