ภาพรวม
ทั้ง const val และ val ใช้สำหรับประกาศค่าที่อ่านอย่างเดียว (read-only) แต่วงจรชีวิต (lifecycle) และข้อจำกัดต่างกันไป
ตารางเปรียบเทียบ
| ลักษณะ | const val | val |
|---|---|---|
| เวลาที่ Initialize | Compile-time (คอมไพล์ไทม์) | Runtime (รันไทม์) |
| ประเภทข้อมูลที่รองรับ | Primitive types และ String เท่านั้น | ทุกประเภท (Object, Function, Class, Collection) |
| ตำแหน่งที่ประกาศได้ | Top-level, Object declaration, Companion object | ทุกที่ (Local, Property, Parameter) |
| สามารถใช้กับ Function ได้ไหม | ไม่ได้ | ได้ |
| Memory | Inline constant (แทนค่าตรงๆ ใน bytecode) | จัดสรรหน่วยความจำปกติ |
| Annotation Target | สามารถเป็น Annotation parameter ได้ | ไม่ได้ |
const val - ค่าคงที่ Compile-time
// ✅ ถูกต้อง - Top level
const val APP_NAME = "MyApp"
const val MAX_RETRY = 3
const val API_BASE_URL = "https://api.example.com"
// ✅ ถูกต้อง - ใน Object declaration
object Config {
const val TIMEOUT = 5000
const val VERSION = "1.0.0"
}
// ✅ ถูกต้อง - ใน Companion object
class MyClass {
companion object {
const val DEFAULT_SIZE = 10
}
}
// ❌ ผิด - ใน Class body (ไม่ใช่ companion/object)
class Wrong {
// const val INVALID = "error" // Compile error
}
// ❌ ผิด - ใช้กับ Function/Object
// const val INVALID = someFunction() // Error
// const val INVALID = MyClass() // Error
val - Read-only Runtime
fun main() {
// ✅ Local val
val localConst = "Hello"
// ✅ รองรับ Function call
val computed = calculateValue() // รันตอน Runtime
// ✅ รองรับ Object instantiation
val myObject = MyClass()
// ✅ รองรับ Collection
val list = listOf(1, 2, 3)
// ✅ Property ใน Class
class User(val name: String) // val ใน Constructor
}
fun calculateValue(): String {
return "Computed at runtime"
}
ตัวอย่างเปรียบเทียบการทำงาน
const val CONST_EXAMPLE = "Compile Time"
val RUNTIME_EXAMPLE = "Runtime: ${System.currentTimeMillis()}"
fun main() {
println(CONST_EXAMPLE) // ค่าคงที่ตลอด
println(RUNTIME_EXAMPLE) // ค่าเปลี่ยนทุกครั้งที่รัน
// const val สามารถใช้ใน Annotation ได้
@MyAnnotation(CONST_EXAMPLE) // ✅ OK
class TestClass
// val ไม่ได้
// @MyAnnotation(RUNTIME_EXAMPLE) // ❌ Error: Annotation parameter must be compile-time constant
}
เมื่อไหร่ควรใช้ const val?
- ค่าคงที่แอปพลิเคชัน: API Keys, URLs, Version, Config คงที่
- ค่าที่ใช้ใน Annotation parameters
- ค่าที่ต้องการ Performance สูงสุด (inline ใน bytecode)
- String literals ที่ใช้ซ้ำหลายที่
สรุป
const val = Compile-time constant, เฉพาะ Primitive/String, ใช้ใน Annotation ได้
val = Runtime read-only, รองรับทุกประเภท, ใช้ได้ทุกที่