1. Ngoại lệ
>
Cuối cùng, các lập trình viên đã nghĩ đến việc tiêu chuẩn hóa và tự động hóa việc xử lý lỗi. Điều này xảy ra khi các ngoại lệ được phát minh. Bây giờ cơ chế ngoại lệ xử lý 80% các tình huống ngoại lệ.
Nếu một học giả nào đó đưa ra các ngoại lệ, thì đó có thể là chủ đề của luận án tiến sĩ của anh ấy hoặc cô ấy. Nếu một lập trình viên nghĩ ra nó, thì anh ta có thể đã nhận được một cái vỗ nhẹ thân thiện từ đồng nghiệp: "Có vẻ ổn đấy, anh bạn."
Khi xảy ra lỗi trong một chương trình Java, chẳng hạn như chia cho 0
, một số điều tuyệt vời sẽ xảy ra:
Bước một
Một đối tượng ngoại lệ đặc biệt được tạo, chứa thông tin về lỗi đã xảy ra.
Mọi thứ trong Java đều là đối tượng và ngoại lệ cũng không phải ngoại lệ 🙂 Đối tượng ngoại lệ có các lớp riêng và điều duy nhất phân biệt chúng với các lớp thông thường là chúng kế thừa lớp Throwable
.
Bước hai
Đối tượng ngoại lệ là "ném". Có lẽ từ ngữ ở đây có thể tốt hơn. "Ném một ngoại lệ" giống như kích hoạt chuông báo cháy hoặc phát ra âm thanh cảnh báo "DEFCON 1".
Khi một ngoại lệ được ném vào máy Java, hoạt động bình thường của chương trình sẽ dừng lại và "các giao thức khẩn cấp" bắt đầu.
Bước thứ ba
Phương thức ném ngoại lệ sẽ thoát ngay lập tức. Ngoại lệ được chuyển đến phương thức gọi, phương thức này cũng thoát ngay lập tức. Và cứ tiếp tục như vậy cho đến khi main
phương thức thoát. Khi main
phương thức kết thúc, chương trình cũng vậy.
Ví dụ:
Mã số | Đầu ra bảng điều khiển |
---|---|
|
|
Một ngoại lệ xảy ra ở dòng 20: chia cho 0. Máy Java ngay lập tức tạo một ngoại lệ — một ArithmeticException
đối tượng và "ném" nó vào phương thức.
Phương divide()
thức kết thúc ngay lập tức, vì vậy chúng ta không bao giờ thấy chuỗi: Không có gì khủng khiếp xảy ra: 0. Chương trình quay lại phương endTheWorld()
thức và tình huống lặp lại: có một ngoại lệ chưa được xử lý trong hệ thống, có nghĩa là phương endTheWorld()
thức cũng kết thúc bất thường. Sau đó, main
phương thức kết thúc và chương trình dừng lại.
Mục đích của những ngoại lệ này là gì? Chà, bạn có thể viết mã của riêng mình để nắm bắt các loại ngoại lệ cụ thể và viết logic của riêng bạn để xử lý các tình huống ngoại lệ.
2. Bắt ngoại lệ:try-catch
Java có một cơ chế bắt ngoại lệ cho phép bạn tạm dừng việc chấm dứt các phương thức bất thường này. Nó trông như thế này:
try
{
// Code where an exception might occur
}
catch(ExceptionType name)
{
// Exception handling code
}
Cấu trúc này được gọi là một try-catch
khối.
Mã có thể xảy ra ngoại lệ được đặt trong dấu ngoặc nhọn, trước từ try
.
Sau dấu ngoặc nhọn, chúng ta có catch
từ khóa và bên trong dấu ngoặc đơn là phần khai báo của một biến ngoại lệ . Tiếp theo là dấu ngoặc nhọn bọc mã sẽ được thực thi nếu xảy ra ngoại lệ của loại được chỉ định .
Nếu không có ngoại lệ nào được đưa ra trong quá trình thực thi " mã chính ", thì mã bên trong khối catch sẽ không được thực thi. Nếu một ngoại lệ xảy ra, thì nó sẽ xảy ra (nếu loại của ngoại lệ được ném ra giống với loại của biến trong ngoặc đơn).
Ví dụ:
Mã số | Đầu ra bảng điều khiển |
---|---|
|
|
3. Nhiều catch
khối
Về lý thuyết, tất cả các loại ngoại lệ có thể được đưa vào một khối mã. Một số bạn sẽ muốn giải quyết theo cách này, một số khác theo cách khác, và vẫn còn những trường hợp khác mà bạn sẽ quyết định không xử lý gì cả.
Các nhà phát triển Java đã quyết định giúp bạn và cho phép bạn viết không chỉ một mà là nhiều catch
khối sau try
khối đó.
try
{
// Code where an exception might occur
}
catch (ExceptionType1 name1)
{
// Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
// Code for handling ExceptionType2
}
catch (ExceptionType3 name3)
{
// Code for handling ExceptionType3
}
Ví dụ:
Mã số | Đầu ra bảng điều khiển |
---|---|
|
|
4. Thứ tự catch
các khối
Các ngoại lệ xảy ra trong một try
khối chỉ có thể được bắt bởi một catch
khối duy nhất. Bạn không thể có tình huống xử lý ngoại lệ trong đó mã từ nhiều catch
khối được thực thi.
Nhưng thứ tự của các khối quan trọng.
Bạn có thể gặp trường hợp một ngoại lệ có thể bị bắt bởi nhiều khối. Nếu đúng như vậy, thì ngoại lệ sẽ bị bắt bởi bất kỳ khối bắt nào đến trước (gần try
khối nhất).
Làm thế nào bạn có thể gặp tình huống nhiều khối bắt có thể bắt cùng một ngoại lệ?
Tất cả các ngoại lệ thuộc về một hệ thống phân cấp thừa kế duy nhất — xem sơ đồ.
Một ArithmeticException
đối tượng có thể được gán cho một biến có kiểu ArithmeticException
hoặc bất kỳ lớp tổ tiên nào của nó: RuntimeException
, Exception
và Throwable
— xem sơ đồ.
Chúng ta sẽ nói nhiều hơn về các lớp kế thừa và tổ tiên ở Cấp độ 21.
Mã này sẽ biên dịch tốt:
Quyền lợi thừa kế: |
---|
|
Vì vậy, bạn có thể bắt một ArithmeticException
với bất kỳ khối nào trong 4 catch
khối trên.
Ví dụ 1:
Mã số | Đầu ra bảng điều khiển |
---|---|
|
|
Trong ví dụ này, the ArithmeticException
có thể bị bắt bởi cả the catch (Exception e)
và catch (ArithmeticException e)
blocks. Nó sẽ bị bắt bởi khối gần try
khối nhất - khối đầu tiên catch
.
Để tránh bất ngờ, tốt nhất là đặt catch
các khối có thể bắt gần như mọi ngoại lệ ở gần cuối danh sách catch
các khối.
Loại này Throwable
thường có khả năng bắt mọi ngoại lệ có thể có trong Java . Nếu bạn đặt nó trong catch
khối đầu tiên, thì mã sẽ không được biên dịch, vì trình biên dịch biết rằng có những khối mã không thể truy cập được.
GO TO FULL VERSION