java是值傳遞還是引用傳遞
java是值傳遞;值傳遞是指在呼叫方法時將實際參數拷貝一份傳遞到方法中,這樣在方法中如果對參數進行修改,將不會影響到實際參數;當傳的是基本型別時,傳的是值的拷貝,對拷貝變數的修改不影響原變數;當傳的是引用型別時,傳的是引用位址的拷貝,但是拷貝的位址和真實位址指向的都是同一個真實數據,因此可以修改原變數中的值。
本教學操作環境:windows10系統、DELL G3電腦。
java是值傳遞還是參考傳遞
Java是值傳遞。
當傳的是基本型別時,傳的是值的拷貝,對拷貝變數的修改不影響原變數;當傳的是引用型別時,傳的是引用位址的拷貝,但是拷貝的位址和真實位址指向的都是同一個真實數據,因此可以修改原變數中的值;當傳的是String類型時,雖然拷貝的也是引用位址,指向的是同一個數據,但是String的值不能被修改,因此無法修改原變數中的值。
首先來解釋什麼是引用傳遞,什麼是值傳遞。
引用傳遞(pass by reference)是指在呼叫方法時將實際參數的位址直接傳遞到方法中,那麼在方法中對參數所進行的修改,將會影響到實際參數。
值傳遞(pass by value)是指在呼叫方法時將實際參數拷貝一份傳遞到方法中,這樣在方法中如果對參數進行修改,將不會影響到實際參數。
那在Java中到底是引用傳遞還是值傳遞呢?其實這個問題也一直是爭論不斷,而且官方也沒給個確切答案。但就我個人理解,Java是值轉遞。
我們先來看一個簡單的例子:
public void test() { int a = 1; change(a); System.out.println("a的值:" + a); } private void change(int a) { a = a + 1; } // 输出 a的值:1
在test()方法中定義了一個基本類型的變數a,然後呼叫change()方法試圖改變這個變量,最後輸出的還是原來的值。
首先我們要清楚,一個方法中的局部變數是存在堆疊中的,如果是基本型別的變數則直接存的是這個變數的值,如果是引用型別的變數則存的是值的位址,指向堆中具體的值。
上面的範例中,呼叫change()方法傳遞的a,其實是a變數的拷貝,不是真正的a,在change()方法中改變的是拷貝,對真正的a是沒有影響的。
這麼一看,Java確實是值傳遞,但我們再看下面這個例子,你就會糾結了
public void test() { User user = new User(); user.setAge(18); change(user); System.out.println("年龄:" + user.getAge()); } private void change(User user) { user.setAge(19); } // 输出 年龄:19
看,物件裡的屬性被改變了,不是值傳遞嗎,應該不會改變啊,這時候就有人總結了,當傳遞值是基本型別時是值傳遞、當傳的是引用型別時是引用傳遞。真的是這樣嗎?
分析這個問題,我們需要知道變數在jvm中是怎麼儲存的。
首先看基本類型,這個很簡單,變數在堆疊中直接存的是值,傳到change()方法的是這個變數的拷貝,因此對拷貝的變數修改不會影響原變數的值。
接著看引用類型,變數在堆疊中儲存的是引用位址,這個位址指向堆中具體的值,如下圖:
當調用change()方法傳入變數時,也是拷貝變量,但是這裡的拷貝只是堆疊中的引用位址,並不會拷貝堆中的數據,因此會變成下圖這樣:
雖然變數是拷貝,但是指向的位址是同一個,因此對變數中的資料修改時,還是會影響到原來真實的變量,但是,如果我們修改的是變數在堆疊中的位址,則不會影響原變量,例如下面這段程式碼:
public void test() { User user = new User(); user.setAge(18); change(user); System.out.println("年龄:" + user.getAge()); } private void change(User user) { user = new User(); user.setAge(19); } // 输出 年龄:18
這種是修改變數在堆疊中的位址,則不會影響原變數。
說到這裡,大家差不多懂了,但是回頭看最開始的那個問題,傳入String類型的變量,String是引用類型,按道理,原變量是會被改變的呀,結果怎麼是不變呢?
String變數比較特殊,我們看String的源碼可以知道,String的值是透過內部的char[]陣列來維護的,但是這個資料定義的是final型別的,因此,String的值是不可變的。我們平常會修改String的值,其實是重新new了一個String對象,例如下面這段程式碼:
String a = "hello"; a = "world";
這段程式碼裡,其實a變數並沒有被修改成world,只是重新new了一個String對象,這個對象的值是world,並把這個對象的引用地址賦給了a,原來的hello還是在堆中,只是這個值沒有被引用,過段時間會被gc垃圾回收。
String變數傳值在記憶體中的變化如下圖:
String拷貝的是變數位址,但是它改變不了原String的值,因為String是不可變的,所以在change()方法中是重新new了一個String對象,改變的是新物件的值,原變數是沒有影響的。
更多相關知識,請造訪常見問題欄位!
以上是java是值傳遞還是引用傳遞的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

膠囊是一種三維幾何圖形,由一個圓柱體和兩端各一個半球體組成。膠囊的體積可以通過將圓柱體的體積和兩端半球體的體積相加來計算。本教程將討論如何使用不同的方法在Java中計算給定膠囊的體積。 膠囊體積公式 膠囊體積的公式如下: 膠囊體積 = 圓柱體體積 兩個半球體體積 其中, r: 半球體的半徑。 h: 圓柱體的高度(不包括半球體)。 例子 1 輸入 半徑 = 5 單位 高度 = 10 單位 輸出 體積 = 1570.8 立方單位 解釋 使用公式計算體積: 體積 = π × r2 × h (4

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

Java是熱門程式語言,適合初學者和經驗豐富的開發者學習。本教學從基礎概念出發,逐步深入解說進階主題。安裝Java開發工具包後,可透過建立簡單的「Hello,World!」程式來實踐程式設計。理解程式碼後,使用命令提示字元編譯並執行程序,控制台上將輸出「Hello,World!」。學習Java開啟了程式設計之旅,隨著掌握程度加深,可創建更複雜的應用程式。