I, Nullable type
- Một trong những vấn đề hay gặp phải nhất với các programming language (bao gồm cả java) là sử dụng 1 null variable (reference) sẽ gây ra null reference exception.
- Trong java, bạn sẽ gặp phải
NullPointerExceptionhayNPE. - Kotlin cung cấp các công cụ để giúp bạn loại bỏ vấn đề trên trong code.
- Do đó kotlin sẽ gặp phải NPE ở 1 trong các trường hợp sau:
- 1, Bạn trực tiếp gọi
throw NullPointerException(). - 2, Sử dụng toán tử
!!trên 1 null reference (mình sẽ nói sau). - 3, Gặp vấn đề khi sử dụng platform type hoặc do java code. Ví dụ: add
nullelement vàoMutableList<String?>. - 4, Liên quan tới việc khởi tạo của 1 object.
- 1, Bạn trực tiếp gọi
- Kotlin giúp chúng ta phân biệt nullable reference và non-nullable reference.
- Ví dụ 1:
1 | var a: String = "abc" // Regular initialization means non-null by default |
- Ví dụ 2:
1 | var b: String? = "abc" // can be set null |
II, Check điều kiện null
- Cách xử lý thông thường giống với java là chúng ta sẽ check xem b có null hay không.
- Ví dụ 3: nếu
bkhác null thì gánl = b.lengthkhông thìl = -1
1 | val l: Int = if (b != null) b.length else -1 |
III, Safe call
- Kotlin cung cấp 1 công cụ khác là
safe call, nó thêm?.vào sau variable. - Ví dụ 4:
1 | val a = "Kotlin" |
Safe call chaincó dạng làv1?.v2?.v3[?.v4[?..]]. Nó rất hữu ích vì nó sẽ returnnullnếu bất cứ variable nào bịnull.- Ví dụ 5: Nếu
parent,parent.child1hayparent.child1.child2returnnull, safe call chain cũng sẽ returnnull
1 | parent?.child1?.child2?.child3 |
- Trong phép gán
=, safe call có thể được đặt bên trái của=. Nếu 1 variable trongsafe call chainreturnnull, việc gán sẽ bị bỏ qua và biểu thức bên phải=sẽ không được gọi. - Ví dụ 6: Nếu
personhayperson.departmenttrả về null,managersPool.getManager()sẽ không được gọi, do đó việc gán bị bỏ qua
1 | person?.department?.head = managersPool.getManager() |
IV, Toán tử Elvis
- Kotlin cũng cung cấp 1 toán tử khác đó là
evils, nó được viết là?:. - Nếu expression bên trái của evils khác
null, kết quả của evils là expression bên trái đó. Nếu không, kết quả của evils là expression bên phải. - Ví dụ 7: Viết lại ví dụ 3 bằng toán tử evils
1 | val l = b?.length ?: -1 |
- Trong kotlin,
returnvàthrowncũng là các expression, do đó chúng có thể được dùng trong expression bên phải của evils. - Ví dụ 8:
1 | val parent = node.getParent() ?: return null |
V, Toán tử !!
- Toán tử
!!không được khuyến khích vì nó xác nhận rằng variable không thể bị null (mặc dù variable vẫn có thể bị null) và sẽ throwNPEkhi variable bị null. - Ví dụ 9: nếu
bcó giá trị null thì code sẽ throwNPE
1 | val l = b!!.length |
VI, Safe cast
- Toán tử cast có thể gây ra
ClassCastExceptionnếu kiểu dữ liệu của variable không thuộc kiểu của class được cast. - Kotlin cung cấp
safe cast, nó được viết làas?. - Safe cast sẽ trả về null nếu việc cast không thành công.
- Ví dụ 10: nêu cast không thành công thì
isẽ có giá trị null
1 | val i: Int? = a as? Int |
V, Null type trong các collection
- Nếu bạn sử dụng collection cho phép các nullable element, bạn có thể lọc để chọn ra những toán tử khác null bằng filterNotNull().
- Ví dụ 11: kết quả của
nonNullNumberslà[1, 2, 4]
1 | val numbers: List<Int?> = listOf(1, 2, null, 4) |