Kotlin pozwala oznaczać gettery i settery właściwości modyfikatorem inline. Daje to kompilatorowi prawo do wstawiania (inlining) kodu akcesora bezpośrednio w miejscach wywołania w celu optymalizacji wydajności.
Przykład:
val foo: Int inline get() = expensiveCalculation()
inline dla gettera/settera, jeśli zawiera reified parametry generyczne lub wyrażenia lambda z cross-linkingiem.Najlepsze praktyki: używaj inline accessor tylko dla bardzo krótkich, często wywoływanych wyrażeń bez efektów ubocznych.
Jeśli do właściwości z inline getter/setter dodasz adnotację z refleksją (na przykład korzystając z KProperty), czy inline będzie działać?
Odpowiedź: Nie. Jeśli właściwość jest używana przez reflection API lub odnosi się do KProperty, kompilator nie będzie mógł wstawić gettera/settera i pozostaną one zwykłymi metodami. Inlining zachodzi tylko przy bezpośrednim odwołaniu w kodzie.
Historia
Utrata wydajności z powodu działania refleksji z inline getter:
Przepisałem gorącą właściwość na inline getter, licząc na eliminację zbędnych wywołań. Później dodano walidację przez KProperty - w efekcie wywołania zaczęły się odbywać przez refleksję, całkowicie niwelując korzyści z inline akcesora.
Historia
Niekorzystne efekty uboczne podczas inlining:
Inline getter robił logowanie:
inline get() { println("dostęp!") return field }
Taka implementacja prowadziła do nieoczekiwanego logowania w wielu miejscach, gdy właściwość była często odczytywana w różnych częściach kodu, co mocno zaśmiecało logi.
Historia
Złamanie ABI z powodu zmiany inline-property:
Zmieniłem logikę inline-gettera w bibliotece, nie przebudowując powiązanych modułów, klienci nadal używali starej sygnatury - rozszerzone ABI plus inlining prowadziło do niekompatybilności i skrytego błędu klientów podczas aktualizacji.