---
# System prepended metadata

title: JAVA 筆記

---

# JAVA 筆記

`Note` `2025.02.28`

 - Start: [time=Wed, May 28, 2025 1:50 PM]
 - Last Update: [time=Mon, Nov 17, 2025 8:52 AM]


## 資料型別與變數宣告
Java 是強型別語言，變數必須先宣告型別才能使用。  

### 原始型別（Primitive Types）
- `int`、`long`、`float`、`double` → 數值  
- `char` → 單一字元  
- `boolean` → `true` / `false`  

```java
int age = 25;
double pi = 3.14159;
char grade = 'A';
boolean isJavaFun = true;
```

### 參考型別（Reference Types）
- `String`、`Array`、`ArrayList`、`HashMap`、自訂 `class`  
- 儲存的是「物件的記憶體位址」  

```java
String name = "Charlie";
int[] numbers = {1, 2, 3};
```


### 資料型別與變數宣告

在 Java 中，變數必須先宣告型別，才能儲存資料。主要分為兩大類：

#### 原始資料型別（Primitive Data Types）
Java 內建 8 種基本型別，直接儲存值（copy by value）。

| 型別      | 位元組 | 範例值 | 範圍 |
|-----------|--------|--------|------|
| `byte`    | 1      | `127`  | -128 ～ 127 |
| `short`   | 2      | `32000`| -32,768 ～ 32,767 |
| `int`     | 4      | `1000` | -2,147,483,648 ～ 2,147,483,647 |
| `long`    | 8      | `100000L` | -9,223,372,036,854,775,808 ～ 9,223,372,036,854,775,807 |
| `float`   | 4      | `3.14f` | 約 ±3.4E38 |
| `double`  | 8      | `3.14159` | 約 ±1.7E308 |
| `char`    | 2      | `'A'`  | Unicode (0 ~ 65535) |
| `boolean` | 1      | `true` | `true` / `false` |

**注意**：
- `long` 常數要加 `L`，例如 `long num = 123456789L;`
- `float` 常數要加 `f`，例如 `float pi = 3.14f;`
- `char` 使用單引號 `'A'`，字串則用雙引號 `"Hello"`


#### 參考資料型別（Reference Data Types）
這類型別不直接存值，而是存「記憶體位址的參考」（copy by reference）。

- 常見的有：`String`, `Array`, `ArrayList`, `HashMap`, `Object`
- 使用者自訂的 `class` 也屬於參考型別

```java
// Primitive 範例
int a = 10;
int b = a;   // copy by value
b = 20;
System.out.println(a); // 仍然是 10

// Reference 範例
StringBuilder x = new StringBuilder("Hi");
StringBuilder y = x;   // copy by reference
y.append("!");
System.out.println(x); // 輸出 "Hi!"
```


#### 常數（final）
如果變數值不允許被修改，可以用 `final` 宣告：

```java
final double PI = 3.1415926;
// PI = 3.15; // X 編譯錯誤，因為 final 不能再被修改
```


#### 小結
- **Primitive**：直接存值，複製時互不影響
- **Reference**：存位址，複製時會指向同一物件
- **final**：宣告常數，值不可變


## 控制流程
控制程式執行的邏輯分支與迴圈。


### 語法基礎

- 資料型別與變數宣告
- 控制流程：`if`, `switch`, `for`, `while`
- 陣列與集合：`Array`, `ArrayList`, `HashMap`
- 方法與參數傳遞（值 vs 參考）

```java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}
```

### 條件判斷
#### If
```java
int score = 85;
if (score >= 90) {
    System.out.println("優秀");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}
```

#### Switch
```java
int day = 3;
switch (day) {
    case 1: System.out.println("星期一"); break;
    case 2: System.out.println("星期二"); break;
    case 3: System.out.println("星期三"); break;
    default: System.out.println("其他");
}
```

### 迴圈
```java
// for
for (int i = 0; i < 5; i++) {
    System.out.println("i = " + i);
}

// while
int j = 0;
while (j < 5) {
    System.out.println("j = " + j);
    j++;
}
```


## 陣列與集合
### 陣列（Array）
固定長度，元素型別一致。
```java
int[] arr = {10, 20, 30};
System.out.println(arr[1]); // 20
```

### ArrayList
可動態增減元素。
```java
import java.util.ArrayList;

ArrayList<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
System.out.println(list.get(0)); // Java
```

### HashMap
鍵值對（Key-Value）結構。
```java
import java.util.HashMap;

HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 3);
map.put("banana", 5);
System.out.println(map.get("apple")); // 3
```


#### 方法與參數傳遞
Java 方法可重複使用程式碼，並支援「值傳遞」與「參考傳遞」。

#### 值傳遞（Primitive）
```java
public static void changeValue(int x) {
    x = 100;
}

public static void main(String[] args) {
    int a = 10;
    changeValue(a);
    System.out.println(a); // 仍然是 10
}
```

#### 參考傳遞（Reference）
```java
public static void changeArray(int[] arr) {
    arr[0] = 99;
}

public static void main(String[] args) {
    int[] nums = {1, 2, 3};
    changeArray(nums);
    System.out.println(nums[0]); // 99
}
```


#### Hello World 範例
```java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}
```

說明：  
- `public class HelloWorld` → 定義一個類別  
- `public static void main(String[] args)` → 主程式進入點  
- `System.out.println()` → 輸出文字到終端機  


## 物件導向設計（OOP）
### 比較表

| 概念名稱 (中文) | 英文名稱 (English) | 核心定義與關係 | 範例程式碼 (Code Snippet) |
| :--- | :--- | :--- | :--- |
| **類別** | **Class** | **藍圖 (Blueprint) 或模板。** 它定義了物件的屬性與行為。 | `public class Car { }` |
| **物件** | **Object** | **實體 (Entity) 或實例 (Instance)。** 它是根據類別所建立出來的具體實體。 | `Car myCar = new Car();` |
| **實例** | **Instance** | 物件的同義詞，一個物件就是一個類別的實例。 | `myCar` |
| **實例化** | **Instantiation** | 建立物件的過程，使用 `new` 關鍵字。 | `new Car()` |
| **屬性** | **Attribute / Field** | 類別中的資料成員，描述物件的**狀態**。 | `public String color;` |
| **方法** | **Method** | 類別中的函數成員，描述物件的**行為**。 | `public void startEngine() { ... }` |
| **建構子** | **Constructor** | 在物件被實例化時自動呼叫，用於**初始化屬性**。 | `public Car(String c) { this.color = c; }` |
| **`this` 關鍵字** | **`this` keyword** | 代表**當前物件實例**本身。 | `this.color = color;` |
| **封裝** | **Encapsulation** | **物件導向三大特性之一。** 將資料 (屬性) 和方法 (行為) 綑綁在一起，並使用 `private` 隱藏內部細節，僅透過 `public` 方法 (Getter/Setter) 供外部安全存取。 | `private String name;` <br> `public String getName() { return name; }` |
| **繼承** | **Inheritance** | **物件導向三大特性之一。** 允許子類別繼承父類別的屬性和方法，實現程式碼重用。 | `public class SportsCar extends Car { }` |
| **多型** | **Polymorphism** | **物件導向三大特性之一。** 「一個介面，多種行為」。指一個物件可以呈現多種型態，並根據實際物件類型執行對應的方法。主要體現為：<br>1. **覆寫 (Overriding)：** 子類別重新實作父類別的方法。<br>2. **多載 (Overloading)：** 同一名稱的方法，但參數列表不同。 | `Car c = new SportsCar();` <br> `c.startEngine();` (執行 SportsCar 的方法) |
| **靜態成員** | **Static Member** | 屬於**類別本身**，不屬於任何特定物件實例，所有實例共享。 | `public static int wheelCount = 4;` |
| **抽象類別** | **Abstract Class** | 不能被直接實例化，用作其他類別繼承的基礎模板。 | `public abstract class Vehicle { ... }` |
| **介面** | **Interface** | 一種純粹的**規格**或**契約**，只包含方法簽章 (沒有實作細節)。 | `public interface Drivable { void drive(); }` |

- **補充說明**：封裝 (Encapsulation)
封裝的核心目的是保護資料的完整性和隱密性，並提高程式的穩定性。

  **實踐方式**： 通常將類別的資料成員 (Fields) 宣告為 private，讓外部無法直接存取和修改。

  **介面提供**： 接著提供 public 的 Getter (讀取資料) 和 Setter (寫入資料) 方法，作為外部與內部資料溝通的唯一管道。這樣可以在 Setter 方法中加入邏輯檢查（例如：年齡不能為負數），以控制資料的有效性。

- **補充說明**：**多型** (Polymorphism)
多型的核心概念是讓程式碼更具彈性和擴展性。

Java 採用 **物件導向程式設計（Object-Oriented Programming, OOP）**，核心概念包含：  

- 類別與物件
- 封裝、繼承、多型
- `interface` vs `abstract class`

```java
interface Sorter {
    void sort(int[] arr);
}

class BubbleSorter implements Sorter {
    public void sort(int[] arr) {
        // 泡泡排序邏輯
    }
}
```


#### 類別與物件（Class & Object）
- **類別（Class）**：定義資料結構與行為的「藍圖」  
- **物件（Object）**：依照類別建立的實體  

```java
class Student {
    String name;
    int age;

    void study() {
        System.out.println(name + " 正在學習 Java");
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student(); // 建立物件
        s1.name = "Hsieh";
        s1.age = 25;
        s1.study(); // 輸出：Hsieh 正在學習 Java
    }
}
```


### Encapsulation

```java=
public class Person {
    // 私有欄位：外部無法直接存取
    private String name;
    private int age;

    // 建構子
    public Person(String name, int age) {
        this.name = name;
        setAge(age); // 使用 setter 方法以便驗證
    }

    // 公開的 getter 方法
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    // 公開的 setter 方法，加入驗證邏輯
    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        if (age >= 0) {
            this.age = age;
        } else {
            System.out.println("年齡不能是負數！");
        }
    }
}
```

```java=
public class Main {
    public static void main(String[] args) {
        Person p = new Person("Alice", 25);
        System.out.println(p.getName()); // 輸出：Alice
        System.out.println(p.getAge());  // 輸出：25

        p.setAge(-5); // 嘗試設定非法年齡，會觸發驗證
        System.out.println(p.getAge());  // 輸出仍為：25
    }
}
```


#### 封裝（Encapsulation）
- 將資料與方法「包裝」在類別中，並透過 **存取修飾子** 控制可見性  
- 常見修飾子：`public`, `private`, `protected`  
- 好處：保護資料、避免外部隨意修改  

```java
class Account {
    private int balance = 1000;

    public int getBalance() {
        return balance;
    }

    public void deposit(int amount) {
        if (amount > 0) balance += amount;
    }
}
```


#### 多型（Polymorphism）
- 相同的方法呼叫，依物件型別不同而有不同表現  
- 透過 **方法覆寫（Override）** 或 **介面實作** 達成  

```java
class Animal {
    void speak() {
        System.out.println("動物發出聲音");
    }
}

class Dog extends Animal {
    @Override
    void speak() {
        System.out.println("汪汪！");
    }
}

class Cat extends Animal {
    @Override
    void speak() {
        System.out.println("喵喵！");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal a1 = new Dog();
        Animal a2 = new Cat();
        a1.speak(); // 汪汪！
        a2.speak(); // 喵喵！
    }
}
```


### Inheritance

```java=
// 父類別
class Animal {
    String name;

    public void eat() {
        System.out.println(name + " is eating.");
    }
}

// 子類別
class Dog extends Animal {
    public void bark() {
        System.out.println(name + " is barking.");
    }
}
```

```java=
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.name = "Buddy";
        myDog.eat();   // 繼承自 Animal
        myDog.bark();  // Dog 自己的方法
    }
}
```

---

```java=
interface A {
    void methodA();
}

interface B extends A {
    void methodB();
}

class MyClass implements B {
    public void methodA() {
        System.out.println("methodA 實作");
    }

    public void methodB() {
        System.out.println("methodB 實作");
    }
}
```

```java=
public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.methodA(); // 輸出：methodA 實作
        obj.methodB(); // 輸出：methodB 實作
    }
}
```

```java=
interface X {
    void x();
}

interface Y {
    void y();
}

interface Z extends X, Y {
    void z();
}
```


### Abstract Class

| 特性             | 抽象類別 (`abstract class`) | 介面 (`interface`)         |
|------------------|-----------------------------|-----------------------------|
| 是否可包含實作   | **V** 可以                     | **V** Java 8+ 可有 default 方法 |
| 是否可有建構子   | **V** 可以                     | **X** 不可                     |
| 多重繼承支援     | **X** 不支援類別多重繼承       | **V** 可實作多個介面           |
| 成員修飾詞       | 可用 `private`, `protected` | 預設為 `public`             |

```java=
// 抽象類別
abstract class Animal {
    String name;

    // 抽象方法：沒有方法體，子類別必須實作
    abstract void makeSound();

    // 一般方法：子類別可以直接使用或覆寫
    public void sleep() {
        System.out.println(name + " is sleeping.");
    }
}
```

```java=
class Dog extends Animal {
    public void makeSound() {
        System.out.println(name + " says: Woof!");
    }
}
```

```java=
public class Main {
    public static void main(String[] args) {
        Dog myDog = new Dog();
        myDog.name = "Buddy";
        myDog.makeSound(); // 輸出：Buddy says: Woof!
        myDog.sleep();     // 輸出：Buddy is sleeping.
    }
}
```


#### `interface` vs `abstract class`
- **interface（介面）**：定義「行為規範」，不能有實作（Java 8+ 可有 `default` 方法）  
- **abstract class（抽象類別）**：可包含「部分實作」與「抽象方法」  

| 特性 | interface | abstract class |
|------|-----------|----------------|
| 多重繼承 | **V** 可實作多個 | **X** 只能繼承一個 |
| 成員變數 | 預設 `public static final` | 可有一般屬性 |
| 方法 | 抽象方法（Java 8+ 可有 `default`） | 可有抽象與具體方法 |
| 使用場景 | 定義規範（行為契約） | 提供部分共用邏輯 |

```java
interface Sorter {
    void sort(int[] arr);
}

abstract class AbstractSorter {
    abstract void sort(int[] arr);

    void printArray(int[] arr) {
        for (int n : arr) System.out.print(n + " ");
        System.out.println();
    }
}

class BubbleSorter extends AbstractSorter implements Sorter {
    @Override
    public void sort(int[] arr) {
        // 泡泡排序邏輯
    }
}
```


#### 小結
- **類別與物件**：藍圖與實體  
- **封裝**：保護資料，提供介面  
- **繼承**：重用程式碼，建立階層  
- **多型**：相同介面，不同行為  
- **interface vs abstract class**：規範 vs 部分實作  


## 資料結構與演算法
### 演算法與資料結構

- 排序法：泡泡排序、選擇排序、快速排序
- 搜尋法：線性搜尋、二分搜尋
- 樹結構：Binary Tree 範例與遍歷（Pre/In/Post）


#### 泡泡排序法

```java=
public class BubbleSort {

    public static void main(String[] args) {
        int[] arr = {3, 4, 0, 1, 2, 5, 6, 9, 7, 8};
        int arr_n = arr.length;

        System.out.println("arr 陣列的長度 arr_n=" + arr_n);
        System.out.println("arr--- (Original)");

        printArray(arr);

        int i = arr_n;
        while (i > 0) {
            
            int j = 1;
            while (j < i) {
                
                if (arr[j] < arr[j - 1]) {
                    int w = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = w;
                    
                    System.out.println("\nw=" + w + " \t---");
                    printArray(arr);
                }
                
                j++;
            }
            
            i--;
        }

        System.out.println("\n");
        System.out.println("arr--- (Sorted)");

        printArray(arr);
    }

    // 輔助函式：用來列印陣列
    public static void printArray(int[] arr) {
        for (int k = 0; k < arr.length; k++) {
            System.out.print(arr[k] + "\t");
        }
        System.out.println(); // 換行
    }
}
```

- [time=Tue, Nov 11, 2025 9:04 PM]


### 泡泡排序法 物件導向

```java=
import java.util.Arrays;

// 定義一個排序器介面
interface Sorter {
    void sort(int[] arr);
}

// 實作泡泡排序的類別
class BubbleSorter implements Sorter {
    @Override
    public void sort(int[] arr) {
        // 為了避免 NullPointerException，先進行 null 值檢查
        if (arr == null || arr.length <= 1) {
            return;
        }

        int n = arr.length;
        boolean swapped;

        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - i - 1; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交換元素
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            if (!swapped) {
                break;
            }
        }
    }
}

public class OOPSortingExample {

    public static void main(String[] args) {
        int[] arr = {5, 1, 4, 2, 8};
        System.out.println("原始陣列: " + Arrays.toString(arr));

        // 創建一個 BubbleSorter 物件
        Sorter mySorter = new BubbleSorter();

        // 呼叫物件的方法來進行排序
        mySorter.sort(arr);

        System.out.println("排序後的陣列: " + Arrays.toString(arr));
    }
}
```

- [time=Mon, Nov 17, 2025 8:52 AM]


### Binary Tree

```java=
public class BinaryTree {

    // 定義二元樹節點結構
    static class Node {
        int data;
        Node left;
        Node right;

        Node(int data) {
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }

    // 建立新節點
    static Node createNode(int data) {
        return new Node(data);
    }

    // 修改節點資料
    static void modifyNode(Node node, int newData) {
        if (node != null) {
            node.data = newData;
        }
    }

    // 前序遍歷：根 → 左 → 右
    static void preOrderTraversal(Node root) {
        if (root != null) {
            System.out.print(root.data + " ");
            preOrderTraversal(root.left);
            preOrderTraversal(root.right);
        }
    }

    // 中序遍歷：左 → 根 → 右
    static void inOrderTraversal(Node root) {
        if (root != null) {
            inOrderTraversal(root.left);
            System.out.print(root.data + " ");
            inOrderTraversal(root.right);
        }
    }

    // 後序遍歷：左 → 右 → 根
    static void postOrderTraversal(Node root) {
        if (root != null) {
            postOrderTraversal(root.left);
            postOrderTraversal(root.right);
            System.out.print(root.data + " ");
        }
    }

    public static void main(String[] args) {
        // 建立節點並構建樹結構
        Node root = createNode(0);
        root.left = createNode(1);
        root.right = createNode(2);
        root.left.left = createNode(3);
        root.left.right = createNode(4);
        root.right.left = createNode(5);
        root.right.right = createNode(6);
        root.left.left.left = createNode(7);
        root.left.left.right = createNode(8);
        root.left.right.left = createNode(9);

        System.out.print("Pre-order Traversal: ");
        preOrderTraversal(root);
        System.out.println();

        System.out.print("In-order Traversal: ");
        inOrderTraversal(root);
        System.out.println();

        System.out.print("Post-order Traversal: ");
        postOrderTraversal(root);
        System.out.println();
    }
}
```
```
Pre-order Traversal: 0 1 3 7 8 4 9 2 5 6
In-order Traversal: 7 3 8 1 9 4 0 5 2 6
Post-order Traversal: 7 8 3 9 4 1 5 6 2 0
```

- [time=Tue, Sep 16, 2025 3:37 PM]


### 二分搜尋法

```java=
public class SortAndSearch {

    // 泡泡排序法
    public static void bubbleSort(int[] arr) {
        int i = arr.length;

        while (i > 0) {
            int j = 1;
            while (j < i) {
                if (arr[j] < arr[j - 1]) {
                    // 交換 arr[j] 和 arr[j-1]
                    int w = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = w;
                }
                j++;
            }
            i--;
        }
    }

    // 二分搜尋法
    public static int binarySearch(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1;

        System.out.println("搜尋對象: " + target);

        while (left <= right) {
            int moderate = (left + right) / 2;
            System.out.println("取中間數: " + moderate);

            if (arr[moderate] == target) {
                return moderate; // 找到目標
            } else if (arr[moderate] < target) {
                left = moderate + 1;
                System.out.println("往右邊找!");
            } else {
                right = moderate - 1;
                System.out.println("往左邊找!");
            }
        }

        return -1; // 沒找到
    }

    public static void main(String[] args) {
        // 未排序的陣列
        int[] arr = {5, 2, 9, 1, 7, 6, 3, 8, 0, 4};
        int target = 2;

        System.out.print("原始陣列：\t");
        for (int value : arr) {
            System.out.print(value + " ");
        }
        System.out.println();

        // 排序陣列
        bubbleSort(arr);

        System.out.print("排序後的陣列：\t");
        for (int value : arr) {
            System.out.print(value + " ");
        }
        System.out.println();

        // 查找目標值
        int result = binarySearch(arr, target);
        if (result != -1) {
            System.out.printf("找到數值 %d 在索引位置 %d。\n", target, result);
        } else {
            System.out.printf("找不到數值 %d。\n", target);
        }
    }
}
```
```
Output:

原始陣列：	5 2 9 1 7 6 3 8 0 4 
排序後的陣列：	0 1 2 3 4 5 6 7 8 9 
搜尋對象: 2
取中間數: 4
往左邊找!
取中間數: 1
往右邊找!
取中間數: 2
找到數值 2 在索引位置 2。
```

- [time=Tue, Sep 16, 2025 3:51 PM]


### 測試與除錯

- 單元測試：JUnit 基礎
- 例外處理：`try-catch-finally`
- 日誌紀錄：`System.out` vs `Logger`


在 Java 中，**命令列輸入（Command Line Input）** 主要有三種常見方式，依需求不同可以選擇：  


#### 使用 `args[]` 接收命令列參數
這是最基本的方式，直接透過 `main(String[] args)` 取得執行程式時輸入的參數。  

```java
public class Echo {
    public static void main(String[] args) {
        for (String s : args) {
            System.out.println("輸入參數: " + s);
        }
    }
}
```

執行方式（假設檔名為 `Echo.java`）：  
```bash
javac Echo.java
java Echo Hello 123 World
```

輸出：  
```
輸入參數: Hello
輸入參數: 123
輸入參數: World
```

- 適合用於「一次性」傳入參數，例如檔案名稱、設定值。


#### 使用 `Scanner` 讀取使用者輸入
`Scanner` 是最常用的互動式輸入工具，能讀取字串、整數、浮點數等。  

```java
import java.util.Scanner;

public class InputExample {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("請輸入名字: ");
        String name = sc.nextLine();

        System.out.print("請輸入年齡: ");
        int age = sc.nextInt();

        System.out.println("Hello " + name + ", 你今年 " + age + " 歲。");
    }
}
```

執行後會等待使用者輸入：  
```
請輸入名字: Hsieh
請輸入年齡: 25
Hello Hsieh, 你今年 25 歲。
```

- 適合互動式程式，例如問答、表單輸入。


#### 使用 `BufferedReader`（較舊但效能佳）
比 `Scanner` 更早出現，適合需要快速讀取大量文字的情境。  

```java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class BufferedInput {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        System.out.print("請輸入一句話: ");
        String line = br.readLine();

        System.out.println("你輸入的是: " + line);
    }
}
```

- 適合處理大量文字輸入（例如讀檔、批次輸入）。


#### 使用 `Console`（進階）
`System.console()` 可讀取輸入，並支援「隱藏輸入」（例如密碼）。  
- 注意：在 IDE（如 IntelliJ、Eclipse）中通常無法使用，需在終端機執行。  

```java
public class ConsoleInput {
    public static void main(String[] args) {
        java.io.Console console = System.console();
        if (console != null) {
            String user = console.readLine("請輸入使用者名稱: ");
            char[] pwd = console.readPassword("請輸入密碼: ");
            System.out.println("使用者: " + user);
        } else {
            System.out.println("Console 不可用，請在終端機執行。");
        }
    }
}
```


#### 小結
- **`args[]`** → 適合一次性參數（如檔案路徑）。  
- **`Scanner`** → 最常用，適合互動式輸入。  
- **`BufferedReader`** → 效能佳，適合大量文字。  
- **`Console`** → 支援隱藏輸入，適合密碼輸入。  


### 專案結構與模組化

- `package` 使用與命名慣例
- 多檔案專案架構
- Maven/Gradle 基礎


### 延伸應用（模組）

- Java GUI：Swing / JavaFX
- Java Web：Servlet / Spring Boot
- Android 開發（Java 基礎）


#### Acknowledge

* [C筆記](https://hackmd.io/@EIT-/c_)
* [排序與二元樹_Java](https://hackmd.io/@EIT-/algo_java)
* [Java SE8 OCAJP專業認證指南](https://www.books.com.tw/products/E050057008?sloc=main)
* [Java SE8 OCPJP進階認證指南](https://www.books.com.tw/products/E050057009?loc=P_br_r0vq68ygz_D_2aabd0_C_2)
* [圖說演算法：使用Java](https://www.books.com.tw/products/0010845577?srsltid=AfmBOorSBSqLayCMDhKlKUbhG0chwU_glufk4z3ZesciogVpXzFTCEqK)