對於賦值操作符=與值/引用類型的理解,賦值操作符,值類型與引用類型

個人網站:
http://riun.xyz


int x = 1;
User u = new User();

如果突然讓我看這兩句代碼,並讓我解釋,我一定會說”定義一個int類型的變量x,把1賦給x;定義一個User類型的變量u,然後在堆區開闢(申請,創建)一塊內存空間存放User(),接着將內存空間的地址值賦給u“。

但是仔細想想,同樣是賦值符號 =,爲什麼一個是賦值(內存空間中存的值),一個是賦地址值(內存空間的地址)呢?

原來我忽略了一個地方,new是一個”函數“,它創建內存空間,並返回所創建內存空間的地址值。所以是new把地址值返回了,被返回的這個東西作爲值賦給了u。所以也是賦值。

以前畫過類似的圖,其實都是不大正確的,這種圖能表現出賦值結果的情況,但是錯誤的展示了賦值符號的執行情況。【因爲按照下圖來看,一個是將內存空間中的值賦給變量,另一個是將內存空間的地址值賦給變量】

在這裏插入圖片描述

所以賦值符號 = ,在任何情況下都只是賦”值“。**它只負責把右操作數對應的內存空間中儲存的東西拿出來,放在左操作數對應的內存空間中。**無論操作數是值類型,還是引用類型。

值類型和引用類型在表現上的不同,不是因爲賦值符號 = 引起的。而是因爲變量內部儲存的東西引起的。

要了解值類型和引用類型,首先要知道值類型和引用類型本身是名詞,說的是不同的類型;接着他們也是形容詞,是用來形容某種 數據類型 是什麼類型的。所以你可以像這樣說:int數據類型是值類型,String數據類型是引用類型。

值類型儲存的是基本的值,這些值是常量,儲存在內存中的常量區,由於是常量,所以是不可變的,這就導致了它的一些特性。

比如

int x = 1;
int y = x;
x = 2;
printf("%d",y);

以上代碼邏輯無論換做任何語言,最後輸出y的值均爲1。其根本原因有兩個:

1、賦值 = 符號的特性(上面說的)

2、常量是不可變的

接下來我們分開解析上面的代碼來說明爲什麼上述兩個原因導致了最後輸出爲1.

int x = 1,將常量區的某塊儲存着1的內存空間的值賦給x(將1賦給x)

int y = x,將變量x所在的內存空間中的值賦給y(將1賦給y),由於賦值符號 = 的特性,所以這裏只是把x中儲存的值1賦給了y所在的內存空間,所以y表現出來也是1

x = 2,將常量區的某塊儲存着2的內存空間的值賦給x(將2賦給x),由於常量是不可變的,所以不能把原來1所在內存空間中儲存的1修改爲2。必須重新找儲存着2的內存空間,將值賦給x。

由於以上原因,這樣對x的修改就不會影響到y了。即使曾經執行過 y = x的操作。

引用類型儲存的是組合的值,這些值由不同的內存空間儲存,這些內存空間各自獨立,排列在一起作爲一個整體展現給外界,外界只看到整個整體的儲存空間。類似下面這樣。引用類型其實是相當於利用一箇中間盒子,將多個值類型組合在一起,裝在盒子裏,由於有了盒子的存在,所以就會有另外的一些特性。

比如

User u1 = new User(18, "hanxu");
User u2 = u1;
System.out.println(u2); //User{age=18, name='hanxu'}
u1.setAge(20);
System.out.println(u2); //User{age=20, name='hanxu'}

以上代碼邏輯換做任何語言,輸出都相同(C語言中的struct關鍵字情況不一樣是因爲struct結構體是值類型,此處的前提是類Class)。其根本原因有三個:

1、賦值 = 符號的特性(上面說的)

2、常量是不可變的

3、中間人User類型的存在

仍然是上述分析步驟,不過由於User類型的存在,它像一個袋子一樣,將int ageString name裝起來,無論袋子裏的東西是值類型還是引用類型,對外界是不可見的,對外界來說只是拿着這個袋子,袋子裏面裝的東西修改,但是袋子本身並不會修改。所以所有拿到相同袋子的人(u1和u2)發生的變化都會同步。

在這裏插入圖片描述

值類型就相當於一包未開封的薯條,現在我拿着一包薯條,突然不想吃了,想換一包蝦條,那麼只有把整個薯條都拿走,再拿來一包蝦條,對我來說我手裏是從拿着薯條到換成了蝦條,拿的東西發生了根本的改變。

引用類型就相當於一個大的購物袋,裏面放着薯條,蝦條,果凍,牛奶。我現在想換掉其中的果凍,換成了幹吃麪,那麼對我來說,裏面的東西雖然已經不一樣了。但我還是拿着包裝袋。(這個比喻有助於理解它們的區別,但是不能說明發生的現象,我實在想不出其他比喻了。要理解現象的原因請還是仔細閱讀上述解釋文字。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章