背景
今天在公司做需求的時候,突然遇到了這個問題,八股文背過,但是又記不大清楚了。索性寫下來,方便我這笨蛋腦子下次看。
解釋
理解這個問題在於看它的角度(強調、加粗)
那我們開始,Java中一切都是值傳遞(中心句),基本變量傳遞的實際的值,比如 int a=3
會將 3
傳遞進去;引用變量傳遞的是地址,比如 User user=new User()
會將 user 所在的地址傳遞進去。
從 角度
來分析
所謂值傳遞,基本變量本身的 值
就是這裏的值, 引用變量的 地址
就是這裏的值。
String 及包裝類型也是值傳遞,因爲這些對象不可變(Immutability)具體可參考:https://stackoverflow.com/questions/1552301/immutability-of-strings-in-java
從 可見性
來分析
基本變量:
先需要了解,局部變量會放在棧中,成員變量會放在堆中,如下圖所示:
一個方法對應一個棧幀,方法結束後棧幀便會彈出
在上圖中,test 方法棧幀感知不到 change 方法的變化,所以當 change 方法棧幀彈出後,test 方法依舊會輸出 3 。
引申一下:現在一個公司需求 A系統、B系統 要同時操作一個數據,並要求實時感知數據變化,那我們可以怎麼做?最簡單的辦法,加一箇中間件,例如redis。需要注意數據一致性。
引用變量:
如果是修改引用變量,那麼便會修改堆中的數據,多個棧幀對應一個堆中對象,無論哪個方法修改了數據,其他方法再次訪問都會感知變化。