# IS216 – Lập Trình Java: Chương 3 – Ngoại Lệ (Exception) và Lambda Expressions

---

## Tổng quan về giáo trình

**IS216 – Lập Trình Java** là học phần thuộc nhóm kiến thức chuyên ngành trong chương trình đào tạo kỹ thuật phần mềm và công nghệ thông tin bậc đại học. Chương 3 tập trung vào hai chủ đề kỹ thuật quan trọng: **Lambda Expressions / Inner Class** và **Exception Handling** – hai nội dung có mối liên hệ thực tiễn cao trong lập trình Java hiện đại.

Mục tiêu học tập của chương này được xác định theo hướng năng lực đầu ra (outcome-based):

- Hiểu và áp dụng cú pháp Lambda Expressions trong các tình huống thực tế.
- Phân biệt Static Inner Class và Non-static Inner Class, nhận diện ngữ cảnh sử dụng từng loại.
- Phân loại ngoại lệ theo ba nhóm: **Error**, **Checked Exceptions** và **Unchecked Exceptions**.
- Lựa chọn và triển khai đúng cơ chế xử lý ngoại lệ phù hợp với từng tình huống.

Cấu trúc chương được tổ chức theo trình tự: giới thiệu công cụ lập trình hàm (Lambda, Inner Class) → khái niệm ngoại lệ → phân loại ngoại lệ → hai phương pháp xử lý (điều kiện/cờ và cơ chế try-catch). Cách tiếp cận này đặt vấn đề thực tiễn trước (chương trình bị ngắt đột ngột là gì?), sau đó dẫn dắt người học đến giải pháp kỹ thuật tương ứng.

Điểm đáng chú ý của chương là việc song hành trình bày cả **nhược điểm của cách tiếp cận điều kiện/cờ** lẫn **ưu điểm của cơ chế try-catch**, giúp người học hiểu lý do kỹ thuật đằng sau các quyết định thiết kế, thay vì chỉ ghi nhớ cú pháp.

---

## Nội dung kiến thức cốt lõi

### Các chủ đề chính trong Chương 3

Chương 3 được cấu trúc thành hai phần lớn, tương ứng với hai khối nội dung độc lập nhưng bổ trợ nhau trong thực hành lập trình Java:

**Phần 1: Lambda Expressions và Inner Class**

Đây là nội dung mở đầu chương, giới thiệu các công cụ lập trình hàm và kỹ thuật tổ chức lớp trong Java. Tài liệu định nghĩa Lambda Expressions là *"biểu thức ẩn danh được sử dụng để biểu diễn một hàm đơn giản"*, với cú pháp gồm ba thành phần: **parameter list** (danh sách tham số), **arrow token** (`->`), và **body** (biểu thức xử lý). Đặc điểm kỹ thuật được nhấn mạnh là *"no return type tường minh – trình biên dịch có thể tự suy luận kiểu dữ liệu trả về dựa vào code thực thi"*.

Ứng dụng của Lambda Expressions được liệt kê cụ thể: sử dụng với Stream API (các phương thức `filter()`, `map()`, `forEach()`), thay thế anonymous inner class, và cải thiện khả năng đọc code. Ví dụ minh họa trong tài liệu sử dụng `List<String>` kết hợp với `forEach()` để xử lý danh sách chuỗi.

Về Inner Class, tài liệu phân loại thành hai dạng:
- **Static inner class**: định nghĩa bằng từ khóa `static`, chỉ truy cập được các biến `static` của outer class.
- **Non-static inner class**: không có từ khóa `static`, có thể truy cập tất cả các biến của outer class.

Ví dụ minh họa trong tài liệu: lớp `OuterClass` chứa biến `private int x = 10` và lớp `InnerClass` bên trong với phương thức `print()` truy cập trực tiếp biến `x`.

**Phần 2: Ngoại lệ và Exception Handling**

Tài liệu định nghĩa ngoại lệ là *"một sự kiện xảy ra trong tiến trình thực thi của một chương trình, làm ngưng tiến trình bình thường của chương trình"*. Các ví dụ được nêu bao gồm: lỗi chia cho 0, vượt kích thước mảng, lỗi mở file, kết nối mạng bị ngắt, JVM hết bộ nhớ.

### Kiến thức nền tảng được xây dựng

**Phân loại ngoại lệ theo ba nhóm:**

| Nhóm | Đặc điểm | Ví dụ trong tài liệu |
|---|---|---|
| **Error** | Lỗi nghiêm trọng, lập trình viên không kiểm soát được | `ThreadDead`, `VirtualMachineError`, `LinkageError` |
| **Checked Exceptions** | Bắt buộc xử lý tại thời điểm viết code, trình biên dịch `javac` kiểm tra | `ClassNotFoundException`, `NoSuchFieldException`, `IOException` |
| **Unchecked Exceptions** | Chỉ xảy ra khi chạy, `javac` không phát hiện lúc biên dịch | `NullPointerException`, `ArrayIndexOutOfBoundsException`, `ArithmeticException` |

Tài liệu làm rõ thêm rằng nhóm Unchecked gồm các lớp `RuntimeException`, `Error` và các lớp con của chúng; trong khi Checked Exceptions là tất cả các ngoại lệ còn lại trong cây phân cấp.

**Cơ chế kế thừa ngoại lệ:**

Toàn bộ hệ thống ngoại lệ Java được xây dựng trên lớp gốc `Throwable`. `ExceptionType` trong cú pháp `catch` được mô tả là *"một đối tượng của lớp Throwable"*, thiết lập nền tảng cho việc hiểu cơ chế bắt và lan truyền ngoại lệ.

**Các RuntimeException cụ thể được phân tích trong tài liệu:**
- `NullPointerException`: xảy ra khi truy cập phần tử qua tham chiếu null (`int[] arr = null; arr[0] = 1`).
- `ArrayIndexOutOfBoundsException`: xảy ra khi vòng lặp `for (i = 0; i <= 4; i++)` truy cập `arr[4]` trong mảng 4 phần tử (chỉ số 0–3).
- `ArithmeticException`: xảy ra tại biểu thức `arr[i-1] / 0` (chia cho số 0).

### Kỹ năng phát triển

Chương 3 hướng tới phát triển các kỹ năng sau:

- **Kỹ năng kỹ thuật**: Viết Lambda Expressions, khởi tạo và sử dụng Inner Class, triển khai khối `try-catch`, đọc tài liệu API Java (tài liệu trích dẫn trực tiếp `BufferedReader` và `Integer` từ Java SE 7 API).
- **Kỹ năng phân tích**: Nhận diện loại ngoại lệ có thể xảy ra tại từng điểm trong code, lý giải tại sao `readLine()` của `BufferedReader` ném `IOException` và `parseInt()` của `Integer` ném `NumberFormatException`.
- **Năng lực thực hành**: Chuyển đổi từ cách tiếp cận điều kiện/cờ sang cơ chế try-catch trong các tình huống cụ thể, đánh giá trade-off giữa hai phương pháp.

---

## Phương pháp giảng dạy và học tập

### Cách tiếp cận sư phạm

Chương 3 áp dụng phương pháp **problem-first** – đặt vấn đề cụ thể trước khi giới thiệu giải pháp kỹ thuật. Điều này thể hiện rõ qua cấu trúc phần Exception Handling: tài liệu trình bày đầy đủ cả ba vấn đề của cách tiếp cận điều kiện/cờ trước khi giới thiệu try-catch:

- **Vấn đề 1**: Phương thức chủ có thể quên kiểm tra điều kiện trả về.
- **Vấn đề 2**: Phải sử dụng một loạt các phép kiểm tra giá trị cờ trả về xuyên suốt chuỗi lời gọi phương thức.
- **Vấn đề 3**: Phương thức chủ có thể không biết cách xử lý khi lỗi xảy ra.

Ví dụ minh họa dùng lớp `Inventory` với phương thức `addToInventory(int amount)`, kiểm tra điều kiện `temp > MAX` và trả về `false`. Chuỗi lời gọi `reference1.method1()` → `reference2.method2()` → `store.addToInventory()` được dùng để minh họa sự lan truyền kiểm tra lỗi theo cách thủ công, từ đó dẫn đến nhược điểm *"khó kiểm soát được hết các trường hợp, lập trình viên thường quên không xử lý lỗi"*.

### Bài tập và ví dụ thực hành

Tài liệu cung cấp ví dụ thực hành hoàn chỉnh xuyên suốt nhiều slide liên tiếp về bài toán đọc dữ liệu từ bàn phím. Luồng thực thi được phân tích từng bước:

1. `BufferedReader.readLine()` → có thể ném `IOException`.
2. `Integer.parseInt(s)` → có thể ném `NumberFormatException`.
3. Khối `try` bao phủ cả hai dòng lệnh.
4. Hai khối `catch` riêng biệt xử lý từng loại ngoại lệ.

Tài liệu còn phân tích luồng thực thi khi ngoại lệ xảy ra: từ lời gọi `Integer.parseInt(s)` trong `Driver.main()`, sang `parseInt()` tạo ra đối tượng `new NumberFormatException()`, rồi trả về khối `catch (NumberFormatException e)` trong caller.

### Hướng dẫn tự học

Tài liệu tham chiếu trực tiếp đến **Java SE 7 API documentation** cho hai lớp:
- `java.io.BufferedReader` (phương thức `readLine() throws IOException`)
- `java.lang.Integer` (phương thức `parseInt(String s) throws NumberFormatException`)

Đây là định hướng để người học tự tra cứu và mở rộng kiến thức thông qua tài liệu chính thức của Oracle.

### Phương pháp đánh giá ngụ ý

Cấu trúc nội dung gợi ý các hình thức đánh giá sau: nhận diện loại ngoại lệ từ đoạn code cho sẵn, viết lại code sử dụng try-catch thay thế cho cách tiếp cận điều kiện/cờ, và phân tích chuỗi lời gọi phương thức để xác định nơi ngoại lệ có thể phát sinh.

---

## Điểm nổi bật và cập nhật

### Tích hợp Lambda Expressions

Việc đặt Lambda Expressions và Inner Class ở đầu chương trước khi vào Exception Handling phản ánh định hướng Java hiện đại (từ Java 8 trở đi). Lambda Expressions được giới thiệu cụ thể trong bối cảnh Stream API, thể hiện sự tích hợp của functional programming vào Java – một xu hướng đã trở thành tiêu chuẩn trong thực tế phát triển phần mềm.

### Kết nối với API thực tế

Tài liệu dẫn trực tiếp URL đến Java SE 7 API documentation, thay vì chỉ mô tả lý thuyết. Đây là cách tiếp cận định hướng thực hành: người học được làm quen với thói quen tra cứu tài liệu kỹ thuật – kỹ năng cần thiết trong môi trường làm việc thực tế.

### Ví dụ code tích hợp

Đoạn code minh họa ba loại `RuntimeException` (NullPointerException, ArrayIndexOutOfBoundsException, ArithmeticException) được đặt trong cùng một đoạn code liên tục, cho thấy rằng nhiều loại ngoại lệ khác nhau có thể xuất hiện tuần tự trong cùng một luồng thực thi – điều thường xảy ra trong ứng dụng thực tế hơn là từng ngoại lệ riêng lẻ được minh họa cô lập.

### Phân tích so sánh hai cách tiếp cận

Chương dành dung lượng đáng kể để phân tích nhược điểm của cách tiếp cận điều kiện/cờ qua nhiều slide chi tiết, thay vì chỉ giới thiệu try-catch. Cách trình bày này phù hợp với mục tiêu phát triển tư duy kỹ thuật, không chỉ dạy cú pháp.

---

## Đối tượng sử dụng

### Sinh viên

Chương 3 của IS216 phù hợp với sinh viên năm 2–3 ngành Công nghệ Thông tin, Kỹ thuật Phần mềm, hoặc các ngành liên quan đang trong giai đoạn học lập trình hướng đối tượng.

**Kiến thức nền cần có (prerequisites):**
- Nắm vững cú pháp Java cơ bản (biến, vòng lặp, mảng, phương thức).
- Đã học lập trình hướng đối tượng (class, object, inheritance, interface) – các khái niệm này được tài liệu tham chiếu ngầm qua Inner Class và cây kế thừa Throwable.
- Hiểu khái niệm tham chiếu (reference) và vùng nhớ cơ bản – cần thiết để hiểu `NullPointerException` và `OutOfMemoryException`.

### Giảng viên

Tài liệu có thể sử dụng theo cấu trúc buổi học gồm hai phần: phần lý thuyết phân loại và cú pháp, phần thực hành phân tích code và viết lại xử lý ngoại lệ. Cấu trúc slide theo từng vấn đề của cách tiếp cận điều kiện/cờ phù hợp để dùng trong thảo luận nhóm hoặc phân tích trường hợp (case discussion).

### Người tự học

Người tự học Java có thể sử dụng chương này như tài liệu tham khảo kỹ thuật cho phần Exception Handling. Tuy nhiên, cần đọc kết hợp với tài liệu Java SE API chính thức (được trích dẫn trong nội dung) để hiểu đầy đủ chữ ký phương thức và hệ thống ngoại lệ của từng lớp.

---

## Câu hỏi thường gặp

**1. Giáo trình này phù hợp với ai?**

Chương 3 của IS216 phù hợp với sinh viên đang theo học học phần lập trình Java ở mức trung cấp, đã hoàn thành các nội dung về lập trình hướng đối tượng cơ bản. Người học cần đã quen với khái niệm class, object, và cơ bản về tham chiếu trong Java trước khi tiếp cận nội dung về Inner Class và phân cấp ngoại lệ.

**2. Cần kiến thức nền nào để học hiệu quả?**

Tài liệu ngầm yêu cầu người học đã biết: khai báo và sử dụng mảng (để hiểu `ArrayIndexOutOfBoundsException`), cơ chế lời gọi phương thức xuyên nhiều lớp (để hiểu vấn đề lan truyền ngoại lệ), và khái niệm interface/anonymous class (để hiểu ứng dụng của Lambda Expressions). Kiến thức về Stream API sẽ giúp ích cho phần Lambda nhưng không bắt buộc.

**3. Điểm khác biệt so với cách tiếp cận thông thường?**

Thay vì chỉ dạy cú pháp try-catch, tài liệu dành một phần đáng kể để phân tích nhược điểm có hệ thống của cách tiếp cận điều kiện/cờ qua ba vấn đề cụ thể (quên kiểm tra, chuỗi kiểm tra dài, không biết cách xử lý). Cách tiếp cận này giúp người học hiểu *lý do* chuyển sang try-catch, không chỉ học cú pháp.

**4. Làm sao để tự học hiệu quả từ tài liệu này?**

Người tự học nên: (1) chạy thử các đoạn code ví dụ về ba loại RuntimeException để quan sát trực tiếp hành vi; (2) tra cứu API documentation của `BufferedReader` và `Integer` theo link được cung cấp; (3) thực hành viết lại lớp `Inventory` sử dụng try-catch thay vì cách tiếp cận điều kiện/cờ đã trình bày; (4) tự tạo các trường hợp gây ra từng loại ngoại lệ để nhận biết message lỗi tương ứng.

**5. Có tài liệu bổ trợ nào được đề cập?**

Tài liệu trực tiếp dẫn đến hai URL trong Java SE 7 API:
- `https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html`
- `http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html`

Đây là nguồn tham khảo chính thức để mở rộng hiểu biết về ký hiệu `throws` trong chữ ký phương thức và danh sách đầy đủ các ngoại lệ liên quan.

---

## Kết luận

Chương 3 của IS216 – Lập Trình Java xây dựng hai nhóm kỹ năng có liên kết thực tiễn: kỹ thuật viết code ngắn gọn với Lambda Expressions và Inner Class, và kỹ năng xử lý ngoại lệ một cách có hệ thống. Phân loại ngoại lệ thành Error, Checked và Unchecked cùng với phân tích so sánh hai phương pháp xử lý tạo nền tảng để người học đưa ra quyết định kỹ thuật có căn cứ.

Người học có thể tiếp tục với các chủ đề: `throws` và `throw` tường minh, custom exceptions, và `finally` block – những nội dung thường xuất hiện trong các chương tiếp theo của học phần Java bậc đại học. Tài liệu Java SE API được trích dẫn trực tiếp trong chương là nguồn tham khảo phù hợp để mở rộng kiến thức theo hướng tự học.

Content trên bám sát các dữ kiện có thật trong fulltext: tên các lớp (OuterClass, InnerClass, Inventory, BufferedReader, Integer), tên phương thức (readLine(), parseInt(), addToInventory()), URL API được trích dẫn, và ba vấn đề cụ thể của cách tiếp cận điều kiện/cờ. Không có nhận định nào được suy diễn ngoài văn bản gốc.