🔢 Giá trị và Kiểu dữ liệu
🎯 Mục tiêu: Hiểu các kiểu dữ liệu cơ bản trong Kotlin, cách Kotlin tự suy luận kiểu, và sự khác biệt với ngôn ngữ khác.
💡 Khái niệm
Phần tiêu đề “💡 Khái niệm”Mọi giá trị trong Kotlin đều có kiểu dữ liệu (data type). Kotlin là ngôn ngữ statically typed - kiểu được xác định tại compile-time, nhưng bạn không cần khai báo nhờ type inference.
val name = "Bumbii" // Kotlin tự hiểu đây là Stringval age = 25 // Kotlin tự hiểu đây là Intval pi = 3.14 // Kotlin tự hiểu đây là Doubleval active = true // Kotlin tự hiểu đây là Boolean📝 Các kiểu dữ liệu cơ bản
Phần tiêu đề “📝 Các kiểu dữ liệu cơ bản”Số nguyên (Integer Types)
Phần tiêu đề “Số nguyên (Integer Types)”| Kiểu | Kích thước | Phạm vi |
|---|---|---|
Byte |
8 bits | -128 đến 127 |
Short |
16 bits | -32,768 đến 32,767 |
Int |
32 bits | -2³¹ đến 2³¹-1 (~±2.1 tỷ) |
Long |
64 bits | -2⁶³ đến 2⁶³-1 |
val byte: Byte = 127val short: Short = 32000val int = 1000000 // Mặc định là Intval long = 10000000000L // Thêm 'L' cho LongSố thực (Floating-Point Types)
Phần tiêu đề “Số thực (Floating-Point Types)”| Kiểu | Kích thước | Độ chính xác |
|---|---|---|
Float |
32 bits | ~6-7 chữ số thập phân |
Double |
64 bits | ~15-16 chữ số thập phân |
val float = 3.14f // Thêm 'f' cho Floatval double = 3.14159265359 // Mặc định là DoubleKý tự và Chuỗi
Phần tiêu đề “Ký tự và Chuỗi”val char: Char = 'K' // Một ký tự, dùng dấu nháy đơnval string: String = "Kotlin" // Chuỗi, dùng dấu nháy képBoolean
Phần tiêu đề “Boolean”val isActive = trueval hasPermission = false🔍 Type Inference - Điểm mạnh của Kotlin
Phần tiêu đề “🔍 Type Inference - Điểm mạnh của Kotlin”Kotlin tự động suy luận kiểu dữ liệu:
// Không cần khai báo kiểuval message = "Hello" // Stringval count = 42 // Intval price = 99.99 // Doubleval items = listOf(1, 2, 3) // List<Int>
// Khai báo tường minh khi cầnval amount: Long = 100 // Cần Long, không phải Intval rate: Float = 0.5f // Cần Float, không phải Double📊 Literal Formats (Cách viết giá trị)
Phần tiêu đề “📊 Literal Formats (Cách viết giá trị)”Số có thể dùng dấu gạch dưới
Phần tiêu đề “Số có thể dùng dấu gạch dưới”val oneMillion = 1_000_000 // Dễ đọc hơn 1000000val creditCardNumber = 1234_5678_9012_3456Lval socialSecurityNumber = 999_99_9999Lval hexBytes = 0xFF_EC_DE_5Eval bytes = 0b11010010_01101001_10010100_10010010Hệ số khác
Phần tiêu đề “Hệ số khác”val decimal = 42 // Thập phânval hexadecimal = 0x2A // Thập lục phân (= 42)val binary = 0b101010 // Nhị phân (= 42)⚠️ Điểm khác biệt quan trọng với Java
Phần tiêu đề “⚠️ Điểm khác biệt quan trọng với Java”1. Không có implicit widening
Phần tiêu đề “1. Không có implicit widening”val intValue: Int = 100
// ❌ Lỗi trong Kotlin// val longValue: Long = intValue
// ✅ Phải convert tường minhval longValue: Long = intValue.toLong()2. Mọi thứ là object
Phần tiêu đề “2. Mọi thứ là object”Trong Kotlin, không có primitive types như Java. Mọi thứ đều là object:
val number = 42println(number.toString()) // OK! Int có methodsprintln(number.plus(8)) // 50println(number.coerceIn(0, 40)) // 40 (giới hạn trong khoảng)3. Nullable types
Phần tiêu đề “3. Nullable types”val nonNull: Int = 42 // Không thể nullval nullable: Int? = null // Có thể null
// Sẽ học chi tiết ở bài Null Safety🎯 Type Conversion (Chuyển đổi kiểu)
Phần tiêu đề “🎯 Type Conversion (Chuyển đổi kiểu)”Kotlin yêu cầu chuyển đổi tường minh:
val intValue = 100val longValue = intValue.toLong()val doubleValue = intValue.toDouble()val stringValue = intValue.toString()
// Các method chuyển đổival byte: Byte = intValue.toByte()val short: Short = intValue.toShort()val float: Float = intValue.toFloat()val char: Char = intValue.toChar()Parse từ String
Phần tiêu đề “Parse từ String”val strNumber = "42"val number = strNumber.toInt() // 42val safeNumber = strNumber.toIntOrNull() // 42 hoặc null
val invalidStr = "abc"// val error = invalidStr.toInt() // ❌ NumberFormatException!val safe = invalidStr.toIntOrNull() // null (an toàn)📐 Any, Unit, và Nothing
Phần tiêu đề “📐 Any, Unit, và Nothing”Any - Cha của tất cả
Phần tiêu đề “Any - Cha của tất cả”val anything: Any = "Hello"val alsoAnything: Any = 42
fun printAnything(value: Any) { println(value)}Unit - Tương đương void
Phần tiêu đề “Unit - Tương đương void”fun printMessage(): Unit { println("Hello")}
// Có thể bỏ qua Unitfun printMessage() { println("Hello")}Nothing - Không bao giờ return
Phần tiêu đề “Nothing - Không bao giờ return”fun fail(message: String): Nothing { throw IllegalStateException(message)}🛠️ Thực hành
Phần tiêu đề “🛠️ Thực hành”Bài tập 1: Xác định kiểu dữ liệu
fun main() { val a = 42 // Kiểu gì? val b = 42L // Kiểu gì? val c = 3.14 // Kiểu gì? val d = 3.14f // Kiểu gì? val e = 'K' // Kiểu gì? val f = "Kotlin" // Kiểu gì? val g = true // Kiểu gì? val h = listOf(1, 2) // Kiểu gì?}Đáp án:
a→Intb→Longc→Doubled→Floate→Charf→Stringg→Booleanh→List<Int>
Bài tập 2: Chuyển đổi kiểu
fun main() { val userInput = "25"
// TODO: Chuyển thành Int và tính tuổi sau 5 năm // TODO: Xử lý trường hợp input không hợp lệ}Lời giải:
fun main() { val userInput = "25"
val age = userInput.toIntOrNull()
if (age != null) { val futureAge = age + 5 println("Sau 5 năm bạn sẽ $futureAge tuổi") } else { println("Tuổi không hợp lệ") }}📱 Trong Android
Phần tiêu đề “📱 Trong Android”// Parse data từ Intent extrasval userId = intent.getIntExtra("USER_ID", -1)val userName = intent.getStringExtra("USER_NAME") ?: "Unknown"
// Parse từ SharedPreferencesval settings = getSharedPreferences("settings", MODE_PRIVATE)val notificationEnabled = settings.getBoolean("notifications", true)val lastSync = settings.getLong("last_sync", 0L)🧠 Kiểu dữ liệu nâng cao (Preview)
Phần tiêu đề “🧠 Kiểu dữ liệu nâng cao (Preview)”Kotlin còn có:
| Kiểu | Mô tả | Sẽ học ở |
|---|---|---|
Array<T> |
Mảng | Bài Collections |
List<T> |
Danh sách | Bài Collections |
Map<K,V> |
Từ điển | Bài Collections |
Data class |
Class chứa data | Bài OOP |
Enum class |
Tập hợp hằng số | Bài OOP |
Sealed class |
Class đóng | Bài OOP |
✅ Checklist - Tự kiểm tra
Phần tiêu đề “✅ Checklist - Tự kiểm tra”Sau bài học này, bạn có thể:
- Liệt kê 8 kiểu dữ liệu cơ bản trong Kotlin
- Hiểu cách Kotlin tự suy luận kiểu (type inference)
- Phân biệt
IntvsLong,FloatvsDouble - Sử dụng underscore trong số lớn (
1_000_000) - Chuyển đổi kiểu với
toInt(),toLong(),toString(), etc. - Sử dụng
toIntOrNull()để parse an toàn
Tiếp theo: Kiểu dữ liệu Số