1. 記憶體的結構
每一台電腦都有隨機存取記憶體(RAM)。那麼,它是什麼、有什麼特性,最重要的是,對我們有什麼用呢?
每個程式(包括用 Java 撰寫的程式)在執行前都會被載入到隨機存取記憶體中。RAM 中同時存放程式碼(由處理器執行)以及程式的資料(由程式自己放入記憶體)。
那麼,RAM 到底是什麼,又像什麼呢?
想像一下 Excel 😎 Excel 的工作表由儲存格組成,而每個儲存格都有其唯一編號(A1、A2、… B1、B2)。只要知道儲存格的編號,就可以往裡面寫入某個值,或讀取其中儲存的值。電腦記憶體的運作方式與此相似。

程式及其資料在執行時儲存在記憶體中。整個電腦記憶體由許多小格子(位元組,byte)組成。每個格子都有唯一的編號——0、1、2、3、…(編號從 0 開始)。知道格子的編號,我們就可以把資料存入該格,或從中取出。在一些格子裡存著程式碼——也就是處理器的指令集,在另一些格子裡則存著該程式的資料。格子的編號也稱為格子的位址。
處理器能夠執行載入記憶體中的程式指令。幾乎所有處理器指令都是這種形式:從若干格子取出資料 → 對它們進行某些運算 → 將結果放入其他格子。
把數百個簡單指令組合起來,我們就能得到複雜且有用的操作。
當在程式碼中宣告變數時,系統會為它配置一塊尚未使用的記憶體。通常是幾個位元組。宣告變數時一定要指定它要儲存的資料型別:數字、文字或其他資料。因為如果不知道資料型別,就無法判斷需要為該變數配置多大的記憶體區塊。
在電腦產業的早期,程式直接與記憶體格子的編號打交道,但後來為了讓程式設計更方便,這些格子就被賦予了名稱。變數的唯一名稱主要是為了讓程式設計師方便;實際上,程式在執行時僅用編號也完全沒問題。
2. 記憶體中的變數
在 Java 中有 4 種主要的整數型別:byte、short、int 和 long。
| 型別 | 大小,位元組 | 名稱來源 |
|---|---|---|
|
|
Byte,因為它佔用一個位元組的記憶體 |
|
|
Short Integer 的縮寫 |
|
|
Integer 的縮寫 |
|
|
Long Integer 的縮寫 |
另外在 Java 中還有 2 種浮點數型別——float 與 double:
| 型別 | 大小,位元組 | 名稱來源 |
|---|---|---|
|
|
Floating Point Number 的縮寫 |
|
|
Double Float 的縮寫 |
每當程式執行到建立變數的指令時,系統都會為它配置一小塊記憶體(大小取決於變數型別)。
變數的位址被認為是為其分配的記憶體區塊中第一個格子的位址。
Java 程式不允許直接存取記憶體。所有與記憶體的互動都只能透過 JVM 完成。
3. 型別 String 在記憶體中的樣子
String 型別可以儲存大量資料,因此它不只是資料型別,而是完整的物件。
String 型別的實際資料(文字)會被放入一個特殊的物件中,會為該物件配置記憶體;而這個物件的位址則會被放入變數中,變數本身也會分配記憶體。

- a 變數的型別為 int,佔用 4 位元組,並儲存值 1。
- b 變數的型別為 int,佔用 4 位元組,並儲存值 10,555。逗號不是小數點,而是千分位分隔符;小數部分用句點分隔。
- d 變數的型別為 double,佔用 8 位元組,並儲存值 13.001。
- str 變數的型別為 String,其值是 D12——指向包含文字之物件的第一個格子的位址。
物件(內含文字)的 String 以獨立的記憶體區塊儲存。其第一個格子的位址存放在變數 str 中。
4. 指派(賦值)時會發生什麼
另一個重要的概念——指派是如何運作的。例如:
int a = 10;
int b = a;
b = 20;
System.out.println(a); // 10
在這個例子中,記憶體中會建立兩個格子:一個給 a,一個給 b。當我們寫下 b = a; 時,被複製的是值(10),而不是那個「盒子」本身。對 b 的更動不會影響 a。
現在來看字串的類似情況:
String s1 = "Hello";
String s2 = s1;
s2 = s2 + " World";
System.out.println(s1); // "Hello"
System.out.println(s2); // "Hello World"
在變更前,s1 與 s2 兩個變數都指向同一個字串 "Hello"。但當我們執行 s2 = s2 + " World"; 時,會為 s2 建立一個新的字串 "Hello World",而 s1 仍然指向原本的 "Hello"。
5. 為什麼在程式設計中幾乎都從 0 開始編號
人們常常好奇,為什麼在程式設計中幾乎處處都從 0 開始計數。其實在許多情況下,從 0 開始更方便(當然也有從 1 開始更方便的情況)。
試著用一個比喻。你正在商店的長隊中,收銀員說:從第 20 位開始的顧客請到第二個櫃台。那他們的編號會是多少?20、21、22、23、… 很合理。那相對於第 20 位呢?0、1、2、3、…
當我們用「第一個元素的編號」加上「數量」來界定一組範圍時,組內的相對編號自然就是 +0、+1、+2、…
在程式設計中也是如此。如果系統為你的變數分配了 100 個位元組,且你有 X——第一個位元組的位址,那麼所有位元組的位址會是什麼?X+0、X+1、X+2、…、X+99。這樣我們就得到了一組索引為 0、1、2、…、99 的位元組。
當我們思考某個資料區塊內的相對位址時,編號自然就會從 0 開始。這就是從 0 開始計數的第一個、也是最常見的原因。
GO TO FULL VERSION