今天發現了乙個比較有意思的問題。把乙個string型別的引數傳入方法,並在方法內改變了引用的值。 然後他在方法外使用這個值,發現這個string還是之前的值,並沒有改變。
這裡要向大家介紹一下,大家都知道j**a在傳參時分為值傳遞和引用傳遞。引數為基本型別時是值傳遞, 引數為封裝型別時是引用傳遞。例如:
public class test
private static void changenum(int num)
}
列印的結果是num=0。
public class test
private static void changeproduct(product p) }
class product
public void setnum(int num)
public string getproname()
public void setproname(string proname)
}
執行的結果是:p.proname=after和p.num=1 。
上面的兩個例子是明顯的值傳遞和引用傳遞。但是如果引數是string型別呢?我們看一下具體的例子:
public class test
private static void changestring(string str)
}
大家猜一下執行結果是什麼呢?按照前面的例子,string應該是乙個封裝型別,它應該是引用傳遞,是可以改變值得, 執行的結果應該是」cd」。我們實際執行一下看看,
str=ab,這如何解釋呢?難道string是基本型別?也說不通呀。
這就要從j**a底層的機制講起了,j**a的記憶體模型分為堆和棧。
1.基本型別的變數放在棧裡;j**a在方法傳遞引數時,是將變數複製乙份,然後傳入方法體去執行。這句話是很難理解的,也是解釋這個問題的精髓。我們先按照這句話解釋一下基本型別的傳遞2.封裝型別中,物件放在堆裡,物件的引用放在棧裡。
1.虛擬機器分配給num乙個記憶體位址,並且存了乙個值0.我們再解釋封裝型別的傳遞:2.虛擬機器複製了乙個num,我們叫他num』,num』和num的記憶體位址不同,但存的值都是0。
3.虛擬機器講num』傳入方法,方法將num』的值改為1.
4.方法結束,方法外列印num的值,由於num記憶體中的值沒有改變,還是0,所以列印是0.
1.虛擬機器在堆中開闢了乙個product的記憶體空間,記憶體中包含proname和num。最後我們再來解釋string在傳遞過程中的步驟:2.虛擬機器在棧中分配給p乙個記憶體位址,這個位址中存的是1中的product的記憶體位址。
3.虛擬機器複製了乙個p,我們叫他p』,p和p』的記憶體位址不同,但它們存的值是相同的,都是1中product的記憶體位址。
4.將p』傳入方法,方法改變了1中的proname和num。
5.方法結束,方法外列印p中變數的值,由於p和p』中存的都是1中product的位址,但是1中product裡的值發生了改變, 所以,方法外列印p的值,是方法執行以後的。我們看到的效果是封裝型別的值是改變的。
1.虛擬機器在堆中開闢一塊記憶體,並存值」ab」。這樣我們理解了j**a在方法傳參的整個過程。其實還是上面那句比較重要的話j**a在方法傳遞引數時,是將變數複製乙份,然後傳入方法體去執行。2.虛擬機器在棧中分配給str乙個記憶體,記憶體中存的是1中的位址。
3.虛擬機器複製乙份str,我們叫str』,str和str』記憶體不同,但存的值都是1的位址。
4.將str』傳入方法體
5.方法體在堆中開闢一塊記憶體,並存值」cd」
6.方法體將str』的值改變,存入5的記憶體位址
7.方法結束,方法外列印str,由於str存的是1的位址,所有列印結果是」ab」
python的引數傳遞是值傳遞還是引用傳遞?
函式引數傳遞機制,傳值和引用的是什麼意思?函式引數傳遞機制問題在本質上是呼叫函式 過程 和被呼叫函式 過程 在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種 值傳遞和引用傳遞。值傳遞 passl by value 過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在堆疊中開闢了記憶體...
python的引數傳遞是值傳遞還是引用傳遞??
函式引數傳遞機制,傳值和引用的是什麼意思?函式引數傳遞機制問題在本質上是呼叫函式 過程 和被呼叫函式 過程 在呼叫發生時進行通訊的方法問題。基本的引數傳遞機制有兩種 值傳遞和引用傳遞。值傳遞 passl by value 過程中,被調函式的形式引數作為被調函式的區域性變數處理,即在堆疊中開闢了記憶體...
Java是值傳遞還是引用傳遞?
廢話不多說,上 很簡單,圖一中呼叫靜態方法intvalues int t 毫無疑問是傳遞值,因為如果是引用傳遞,那麼二者列印的值是一致的。很明顯,a 之後,t的值沒有發生改變。圖二也是一樣,清晰明了,把方法引數的值賦值給a,然後改變a的值,二者值列印均一致,那是因為t代表的是乙個堆記憶體的位址,基本...