轉載請注明原文地址:https://www.cnblogs.com/ygj0930/p/10830521.html
一:區分Java數據類型、變量類型
Java數據類型分兩種:基本數據類型、引用類型。
8種基本數據類型(4整,2浮,1符,1布):byte(最小的數據類型)、short(短整型)、int(整型)、long(長整型);float(浮點型)、double(雙精度浮點型);char(字符型);boolean(布爾型)。
引用類型類型:引用數據類型非常多,如:類、 接口類型、 數組類型、 枚舉類型、 注解類型、 字符串型。“簡單來說,所有的非基本數據類型都是引用數據類型。”
變量類型:相應地,根據變量要存放的數據類型,也區分為:基本類型變量、引用類型變量。
基本類型和引用類型的區分,體現在其對應變量所存儲的內容不同:
基本類型變量:變量存放的就是一個單純的值。
引用類型變量:變量存放的是一個內存地址(引用),該地址指向內存中另一片地址,那片地址才是真正存放對象值的地方。
二:Java傳參時的操作
我們在調用函數時,會將某些變量作為函數參數傳遞進去,調用方法時發生了什么?
這里涉及到形參和實參的概念:
1、在函數定義時所使用的參數,就是形參
定義函數時,函數參數只是作為一個變量、符號,體現在代碼邏輯中,它沒有具體的值。
2、在調用函數時,將值傳給參數后,就是實參
在調用函數時,參數有了具體的值,變得有實際意義,此時稱之為實參。
因此,參數傳遞的實質:就是 為函數形參賦值,使之變成實參數 的過程,也就是說:函數邏輯中所操作的並不是我們傳進去的變量本身,而是copy了變量值的實參。
根據傳遞的數據類型以及函數中對參數的使用操作不同,大致可以分為4種場景:
1、基本數據類型傳遞
由於基本類型變量中存放的就是基本類型值,因此傳遞基本類型變量作為參數時,就是將變量的值,copy給了函數的實參。
因此,在函數中改變實參的值,不會影響函數外部的變量值。
2、immutable的引用類型變量傳遞
對於String,以及Integer、Double等幾個基本類型包裝類,它們的值是不可變的,也就是說:存放包裝類類型的變量值,指向了一個對象地址,而這個變量不能再指向其他地址或存放別的值。
在immutable類型變量的傳遞過程中:會將變量值(引用地址)所指向的內容copy一份,並將復制后的空間的地址傳遞給函數作為實參。也就是說:傳遞給函數的變量所指向的空間,與函數實參所指向的空間是不同的,只不過各自指向的空間中的內容一樣而已。
因此,函數中操作實參,不會影響到函數外部的變量值。
3、變量值可變的引用類型變量傳遞,並在函數中使用該引用去改變內容
對於class、array等普通引用類型,其變量值是一個地址,指向了這些對象真正存放的空間。“可變”的意思是:存放這些數據類型的變量,它可以所存儲的地址,指向別的存儲空間。
在這種類型的變量傳遞給參數的時候:會將變量值(引用地址)copy一份,傳遞給函數作為實參。也就是說:傳遞給函數的變量所指向的空間,與函數實參所指向的空間是相同的。
因此,在函數中通過實參去改變對象的內容,會影響到函數外部變量所指向的對象的內容,因為它們都指向同一個對象。
4、變量值可變的引用類型變量傳遞,但函數中為實參賦新值
與第3點不同,這種場景下,實參在函數中被更改了值,指向了新的地址。
因此,在后續操作中通過實參去改變對象的內容時,不會影響到函數外部變量所指向的內容,因為它們指向了不同對象。
三:結論——Java只有值傳遞
通過上文中關於“參數傳遞的實質”論述可以得知:函數調用時,無論值類型變量還是引用類型變量,都是將變量所存儲的值copy給了函數的實參,區別在於基本類型變量的值就是類型值本身,而引用類型變量的值是一個地址。
也就是說:Java函數調用時,都是值傳遞。