Geschichte der Frage:
In Kotlin erfolgt der Zugriff auf Eigenschaften über Getter- und Setter-Methoden. Um die Leistung zu verbessern, haben die Entwickler den Modifier inline für Accessoren hinzugefügt, der es der JVM ermöglicht, die Aufrufe während der Kompilierung zu optimieren, indem der Körper von get/set direkt in den aufrufenden Code eingesetzt wird.
Problem:
Normale Accessor-Methoden werden für jede Eigenschaft erstellt, was die Overhead-Kosten für den Aufruf erhöht (insbesondere bei häufigem Zugriff). Manchmal verwenden Entwickler separate get/set, wollen aber den Funktionsaufruf-Overhead vermeiden.
Lösung:
Verwenden Sie den Modifier inline für den Getter oder Setter, wenn deren Implementierung kurz ist und es keinen komplexen Code gibt. Dies reduziert die Overhead-Kosten, insbesondere im Hot-Path. Beachten Sie: Inlining funktioniert nur für Top-Level-Eigenschaften und Eigenschaften in Companion-Objekten sowie Object-Objekten, jedoch nicht in normalen Klassen aufgrund der Prinzipien der JVM-Vererbung.
Beispielcode:
inline var Int.asHex: String get() = Integer.toHexString(this) set(value) {} inline val String.firstUpperCase: String get() = if (isEmpty()) this else this[0].uppercase() + substring(1)
Schlüsselmerkmale:
Kann man Inline-Get/Set für normale Klassen-Eigenschaften verwenden?
Nein, Inlining für Getter und Setter ist nur für Top-Level- oder Object-Eigenschaften (einschließlich Companion Object) zulässig, nicht für Eigenschaften innerhalb von Klassen, um Probleme mit der Vererbung zu vermeiden.
Ist der Zugriff auf das Backing Field in einem Inline Accessor verfügbar?
Nein, Inline Accessor hat kein Backing Field, der Versuch, darauf zuzugreifen, führt zu einem Kompilierungsfehler.
Beeinflusst das Inlining des Accessors immer den Bytecode?
Inlining gibt dem Compiler nur einen Hinweis darauf, dass er den Code einfügen kann. Der JIT-Compiler kann dies in einigen Fällen ignorieren. Außerdem kann, wenn der Accessor komplexe Logik enthält, der erzielte Effekt gegenteilig sein.
In einem Projekt wurde eine große Eigenschaft als inline deklariert, aber im Getter wird eine komplexe Umwandlung verarbeitet, die in einer Schleife verwendet wird. Ergebnis: der finale Bytecode wird aufgebläht, JIT deaktiviert das Inlining, die Leistung sinkt.
Vorteile:
Nachteile:
Eine Inline-Val wurde für die Umwandlung einer Zahl in eine Zeichenkette deklariert. Der Getter wird häufig im UI-Code aufgerufen. Die Leistung bleibt hoch, der Bytecode kompakt.
Vorteile:
Nachteile: