什麼是「參考資料形態」
在 Java 中,資料型別可以分為兩大類:
| 分類 |
名稱(英文) |
內容是什麼? |
範例 |
| 基本資料型別 |
Primitive Data Types |
儲存「實際的值」 |
int, double, char, boolean |
| 參考資料型別 |
Reference Data Types |
儲存「記憶體位置」 |
String, 陣列、類別、物件等 |
基本型別:直接存資料
1 2 3 4
| int a = 10; int b = a; b = 20; System.out.println(a);
|
變數 b 是複製 a 的值,兩者互不影響。
參考型別:存的是記憶體地址
1 2 3 4
| int[] arr1 = {1, 2, 3}; int[] arr2 = arr1; arr2[0] = 99; System.out.println(arr1[0]);
|
arr1 和 arr2 指向同一個陣列記憶體位址。
String 字串
String 是一種 不可變物件(immutable)
- 雖然使用上像基本型別,但其實是物件
1 2 3 4
| String a = "Hi"; String b = a; b = "Hello"; System.out.println(a);
|
陣列 Array
1 2
| int[] nums = {10, 20, 30}; String[] names = {"Tom", "Jerry"};
|
- 陣列是物件!
- 用
new 關鍵字建立時,自動配置記憶體於 Heap 區
類別與物件 Class & Object
1 2 3 4 5
| class Dog { String name; } Dog d1 = new Dog(); d1.name = "Bingo";
|
d1 是參考變數,指向 Heap 中的 Dog 物件
記憶體位置解析(Stack vs Heap)
| 名稱 |
放什麼? |
說明 |
| Stack |
基本資料型別、參考位址 |
程式碼執行時快速配置 |
| Heap |
物件內容(實體資料) |
建立物件時存放的區域 |
簡圖說明:
記憶體狀況如下:
d 存在 Stack(存放記憶體地址)
new Dog() 則是 Dog 物件在 Heap(物件真正內容)
傳基本型別 ➜ 傳值(值複製一份)
1 2 3
| void addOne(int x) { x = x + 1; }
|
傳參考型別 ➜ 傳位址(會改到原物件)
1 2 3
| void changeName(Dog d) { d.name = "Coco"; }
|
練習小測驗
Q1:以下輸出是?
1 2 3 4
| String str1 = "Hi"; String str2 = str1; str2 = "Hello"; System.out.println(str1);
|
答案: Hi
Q2:這段程式碼的輸出是?
1 2 3 4
| int[] x = {1, 2, 3}; int[] y = x; y[1] = 100; System.out.println(x[1]);
|
答案: 100
常見錯誤觀念澄清
| 誤解 |
正解 |
String 是基本型別 |
❌ 錯,它是參考型別,但不可變(immutable) |
| 陣列不是物件 |
❌ 錯,陣列是物件,會存在 Heap 中 |
| 方法參數傳物件時,是複製一份 |
❌ 錯,是傳「記憶體位置參考」 |
== 比較的是字串內容 |
❌ 錯,是比記憶體位置,用 .equals() 比內容 |
補充:如何比較兩個字串內容?
1 2 3 4 5
| String a = new String("Hi"); String b = new String("Hi");
System.out.println(a == b); System.out.println(a.equals(b));
|
快速複習
- Java 資料型別分成「基本」與「參考」
- 參考資料會記住「位址」,指向物件內容(堆積區)
- 物件或陣列傳入方法時,會改變原物件內容
- 記憶體有 Stack 和 Heap!
.equals() 才能比字串或物件內容,不要用 ==