Kotlin'de inline class (Kotlin 1.5'ten itibaren - terim "value class"), minimum giderle tiplerin etrafında sarmalar oluşturmanıza olanak tanır. Derleme esnasında bu tür sınıflar, nesne yaratmanın ek maliyetlerinden kaçınmak için arka planda iç değerleri (value) ile değiştirilir.
Sınırlamalar ve özellikler:
=== normal şekilde çalışmaz) için referanslar saklanamaz.Örnek:
@JvmInline value class UserId(val value: String) fun getUser(id: UserId) { println("Loading user with id: ${id.value}") } val id = UserId("XYZ") getUser(id) // Arka planda sadece String ile çalışıyor!
Ne zaman kullanılmalı:
Value class miras alınabilir mi veya arayüz/soyut sınıf hiyerarşisinde kullanılabilir mi?
Cevap: Hayır, value class diğer sınıflardan (arayüzler hariç) miras alamaz, mirasa kapalı olamaz, init bloğu ve diğer dinamik alanları barındırmaz. Tek kullanılabilir seçenek — arayüzleri uygulamaktır.
Örnek:
interface Validatable { fun isValid(): Boolean } @JvmInline value class Email(val raw: String) : Validatable { override fun isValid() = raw.contains("@") }
Hikaye
Android uygulaması, Parcelable parametrelerine value class ekledikten sonra başlatma süresini aniden artırdı: hatalı @Parcelize ile value class kullanmanın, her aşamada boxing/unboxing'e yol açtığı ve inline avantajlarını harcadığı ortaya çıktı.
Hikaye
Mikro hizmet, kimliklerin tip güvenliği için UserId ve ProductId için value class kullanmaya aktif şekilde başladı, ancak birçok yerde generic fonksiyonlar, "sarmanın" çalışmadığı yansıma (reflection) gerektiriyordu. Unit testleri aniden başarısız olmaya başladı, ClassCastException hataları ortaya çıktı.
Hikaye
Java'dan göç eden kod, optimizasyon için iç alan sınıflarını value class ile değiştirmeye başladı, ancak nullable alanlar olarak kullanımı, beklenmeyen null pointer exception'lara yol açıyordu; çünkü value class yalnızca dıştaki değer null olduğunda null olabilir ve bu eski invarinatları bozuyordu.