在Java中按值調用和按引用調用
一、為什么按值調用和按引用調用?
方法或函數可以通過兩種方式調用。一種是按值調用,另一種是按引用調用,這兩種方式通常根據作為輸入或參數傳遞給它們的值的類型來區(qū)分。
在我們開始之前,讓我澄清一件事,在Java中,只有按值調用(值傳遞),沒有按引用調用。
二、按值調用
按值調用是一種方法,通過復制給定變量(或常量或任何保存數據的對象)的實際值,將參數傳遞給函數
這意味著當我們調用一個傳遞參數值的方法時,這個參數值會被復制到內存的一部分(取決于類型),值的副本會被傳遞給調用方法的參數。
在Java中,只有按值調用,沒有按引用調用。
三、引用調用
通過引用調用是一種將值的引用(即地址)傳遞給方法的方法。
這意味著,當我們通過將引用的副本(即地址)傳遞給該方法的值而不是值本身的副本來調用該方法時,調用方法具有該值的引用(即地址)。
當調用方法更改值的引用時,原始引用也會更改。
四、為什么Java中只有按值調用,沒有按引用調用?
根據定義,引用調用是我們傳遞該變量的引用(即地址)的地方。要做到這一點,我們需要首先存儲地址,這將需要一個指針(在C中,其傳遞為*variableName)。正如我們所知,在java中,我們沒有指針,因此不可能傳遞引用(即地址)并執(zhí)行逐引用調用。
Java不支持指針,這就是為什么Java不支持引用調用。但是C/C++支持指針,因此這些語言支持引用調用。
您可能會問,為什么Java不支持指針?好吧,這是另一個有爭議的話題,我們可以在其他文章中討論,直到簽出這個stackoverflow頁面,可以參考,這讓您對它有了一些了解。
但是,我們仍然可以借助對象行為在Java中實現引用調用。
五、Java中的引用調用,但如何調用?
Java總是使用按值調用。這意味著該方法獲取所有參數值的副本,并且該方法不能修改傳遞的變量的內容。Java使用兩種方法參數:
- Java基本類型
- Java對象引用
它看起來非常簡單明了,就像將基本類型傳遞給方法一樣。但在將對象傳遞給該方法時,這是非常引人注目的。當一個對象被傳遞給一個方法時,該方法會獲得對象引用的一個副本,而原始副本和正式副本都引用同一個對象,因此在調用方法中,可以更改對象參數的狀態(tài)。
讓我們通過一個例子來詳細了解上述兩個方法參數。
將Java基本數據類型作為參數傳遞給方法
對于原始數據類型參數,原始值不變。讓我們舉一個簡單的例子:
public class PrimitiveDataInAction {
public static void main(String[] args) {
int someValue = 50;
System.out.println("Before method call :: " + someValue);
modified(someValue);
System.out.println("After method call :: " + someValue);
}
public static void modified(int someValue) {
System.out.println("exiting name :: " + someValue);
// modifying the parameter
someValue = 15;
System.out.println("modified name :: " + someValue);
}
}輸出:
Before method call :: 50
exiting name :: 50
modified name :: 15
After method call :: 50Process finished with exit code 0
當您將原始數據類型變量傳遞給一個方法時,它會為該方法創(chuàng)建一個本地副本,并執(zhí)行方法中提到的任何操作&一旦這個變量從這個方法中出來,方法本地副本就會從內存中刪除
&調用該變量之前加載的前一個值。
六、Java對象引用
對于Java對象引用類型的按值調用,會更改原始值。
讓我們舉一個簡單的例子:
class JavaObjectReferencesInAction {
public static void main(String[] args) {
List <String> listOfString = new ArrayList < > ();
listOfString.add("Mahesh");
System.out.println("Before modified :: " + listOfString);
modified(listOfString);
System.out.println("After modified :: " + listOfString);
}
public static void modified(List < String > listOfString) {
// modifying the string
listOfString.add("Imran");
}
}輸出:
Before modified :: [Mahesh]
exiting listOfString :: [Mahesh]
modified listOfString :: [Mahesh, Imran]
After modified :: [Mahesh, Imran]Process finished with exit code 0
讓我們看看它是如何工作的。
在上面的示例中,我們創(chuàng)建了一個ArrayList對象,并在其中添加了一個字符串值Mahesh?,F在列表中的數據是一個字符串,值為Mahesh。
在下一行中,我們調用了modified方法,該方法獲取一個列表,并向同一給定列表中添加一個字符串Imran
但是當我們調用這個修改過的方法時,Java對象引用代替了值。它傳遞list的引用,list只是list的實際對象
這也會導致修改原始列表。
七、結論
我們詳細討論了一個棘手的面試問題,即Java中的按值調用和按引用調用。對于初學者來說,這可能需要消化很多東西,但相信我,一旦你開始玩它,它就會在你的腦海中清晰地浮現出來。
相關文章
POI XSSFSheet shiftRows bug問題解決
這篇文章主要介紹了POI XSSFSheet shiftRows bug問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
基于Spring BeanUtils的copyProperties方法使用及注意事項
這篇文章主要介紹了基于Spring BeanUtils的copyProperties方法使用及注意事項,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
Java中Stream流中map和forEach的區(qū)別詳解
本文主要介紹了Java中Stream流中map和forEach的區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04
Java?hibernate延遲加載get和load的區(qū)別
這篇文章主要介紹了Java?hibernate延遲加載get和load的區(qū)別,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-09-09
SSM+微信小程序實現物業(yè)管理系統(tǒng)及實例代碼
這篇文章主要介紹了SSM+微信小程序實現物業(yè)管理系統(tǒng),ssm微信小程序物業(yè)管理系統(tǒng),有網站后臺管理系統(tǒng),本文通過實例代碼給大家展示系統(tǒng)的功能,需要的朋友可以參考下2022-02-02

