ProgramlamaKotlin geliştiricisi

Kotlin'da 'inline' anahtar kelimesi sınıflarla (value class/inline class) nasıl uygulanmıştır? Hangi sınırlamalar vardır, bu tür sınıflar bytecode seviyesinde nasıl çalışır, ne zaman ve neden kullanılmalıdır? Bir örnek verin ve tipik zorlukları açıklayın.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

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:

  • Primary constructor'da yalnızca bir özellik olabilir.
  • Referential equality (=== normal şekilde çalışmaz) için referanslar saklanamaz.
  • Value class, miras alınabilen bir sınıf olamaz ve sadece kendi value'su dışında bir durum (state) barındıramaz.
  • Tüm generic tipler ve platform API’leri, inline/value class ile kutulamadan (boxing) çalışamayabilir.
  • Value class, init bloğu, value dışında alanlar ve yalnızca minimum işlevler barındıramaz.

Ö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ı:

  • Kimlikler için tip güvenliğini sağlamak, özel değerleri temsil etmek.
  • Milyonlarca benzer sarmalarla çalışırken performansı artırmak (nesneler oluşturulmaz).

Hileli Soru

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("@") }

Bilgi eksikliğinden kaynaklanan gerçekten gelen hatalara dair örnekler


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.