Kotlin const, var und val Schlüsselwörter

1. Einleitung

In diesem Tutorial werden die wichtigsten Unterschiede zwischen den Schlüsselwörtern const , var und val in der Kotlin-Sprache erläutert .

Um diese Schlüsselwörter in einen Kontext zu setzen, werden wir sie mit ihren Java-Entsprechungen vergleichen.

2. Tippen verstehen

Um diese Schlüsselwörter zu verstehen, müssen wir zwei der Hauptkategorien von Typsystemen verstehen, denen eine Sprache folgen kann - manifestierte Typisierung und abgeleitete Typisierung.

2.1. Manifest Typing

Alle Sprachen bieten eine Reihe primitiver Datentypen zum Speichern und Bearbeiten von Daten in einem Programm. Bei Programmiersprachen, die der Manifest-Typisierungsdisziplin folgen, müssen die Datentypen im Programm explizit definiert sein.

Java folgt bis Version 10 genau dieser Disziplin. Wenn wir beispielsweise eine Nummer in einem Programm speichern möchten, müssen wir einen Datentyp wie int definieren :

int myVariable = 3;

2.2. Abgeleitete Eingabe

Im Gegensatz zu Java folgt Kotlin der abgeleiteten Schreibdisziplin . Sprachen, die Typinferenz unterstützen , erkennen beim Kompilieren automatisch Datentypen innerhalb des Programms.

Diese Erkennung bedeutet, dass wir uns als Entwickler keine Gedanken über die von uns verwendeten Datentypen machen müssen.

3. var

Zunächst beginnen wir mit var , Kotlins Schlüsselwort, das veränderbare, nicht endgültige Variablen darstellt. Nach der Initialisierung können wir die von der Variablen gehaltenen Daten mutieren.

Schauen wir uns an, wie das funktioniert:

var myVariable = 1

Hinter den Kulissen wird myVariable mit dem Datentyp Int initialisiert .

Obwohl Kotlin Typinferenz verwendet, haben wir auch die Möglichkeit, den Datentyp bei der Initialisierung der Variablen anzugeben:

var myVariable: Int = 1

Variablen, die als ein Datentyp deklariert und dann mit einem Wert des falschen Typs initialisiert werden, führen zu einem Fehler:

var myVariable: Int = b //ERROR!

4. val

Kotlin des val Schlüsselwort arbeitet viel in der gleichen wie das var Schlüsselwort, aber mit einem wesentlichen Unterschied - die Variable ist schreibgeschützt. Die Verwendung von val ähnelt der Deklaration einer neuen Variablen in Java mit dem Schlüsselwort final .

Zum Beispiel würden wir in Kotlin schreiben:

val name: String = "Baeldung"

Während wir in Java schreiben würden:

final String name = "Baeldung";

Ähnlich wie eine endgültige Variable in Java muss einer val- Variablen in Kotlin ein deklarierter Wert zugewiesen werden, oder in einem Klassenkonstruktor :

class Address(val street: String) { val name: String = "Baeldung" }

5. const

Wie val sind Variablen, die mit dem Schlüsselwort const definiert wurden, unveränderlich. Der Unterschied besteht darin, dass const für Variablen verwendet wird, die zur Kompilierungszeit bekannt sind.

Das Deklarieren einer Variablen const ähnelt der Verwendung des statischen Schlüsselworts in Java.

Mal sehen, wie man eine const- Variable in Kotlin deklariert :

const val WEBSITE_NAME = "Baeldung"

Und der in Java geschriebene analoge Code wäre:

final static String WEBSITE_NAME = "Baeldung";

5.1. Ständiges Inlining

Ab Kotlin 1.1 fügt der Kotlin-Compiler die const val- Werte an den Stellen ein, an denen sie verwendet werden . Betrachten wir zum Beispiel ein einfaches Beispiel:

const val VALUE: String = "constant" fun main() { println("$VALUE is inlined") }

Auf den ersten Blick könnte man denken, dass der Kotlin-Compiler einen statischen Feldwert von einer Klasse erhält und ihn dann mit dem Text "ist inline" verkettet . Da jedoch const val s inlined werden, wird der Compiler die kopieren „Konstante“ wörtliche wo der VALUE konstant verwendet. Dieses konstante Inlining ist viel effizienter als das Abrufen eines statischen Werts von einer Klasse .

Um zu überprüfen, ob das Inlining tatsächlich unter der Haube erfolgt, können wir den Bytecode überprüfen. Zuerst sollten wir die Kotlin-Datei mit kotlinc kompilieren :

$ kotlinc Main.kt

Dann können wir mit javap einen Blick auf den generierten Bytecode werfen :

$ javap -c -p -v MainKt // truncated 0: ldc #16 // String constant is inlined 2: astore_0 3: iconst_0 4: istore_1 5: getstatic #22 // Field java/lang/System.out:Ljava/io/PrintStream; 8: aload_0 9: invokevirtual #28 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V 12: return

Wie oben gezeigt, wird bei Index 0 das "konstante" Literal zur Verkettung kopiert. Es gibt also keine Möglichkeit , einen Wert aus einem statischen Feld in einer Klasse abzurufen.

Die Quintessenz ist, dass die konstanten Werte zwar wie statische Felder aussehen, aber nicht als öffentliche statische Endfelder implementiert sind . Einfach ausgedrückt ist der const val nur eine Compiler-Illusion.

6. Fazit

In diesem Artikel haben wir uns kurz mit dem Unterschied zwischen manifestierter und abgeleiteter Typisierung befasst.

Dann haben wir uns den Unterschied zwischen Kotlins Schlüsselwörtern var, val und const angesehen .