1. Typisierung

Typumwandlung in Java

Variablen primitiver Typen (mit Ausnahme des booleanTyps) werden zum Speichern verschiedener Arten von Zahlen verwendet. Obwohl sich die Variablentypen nie geändert haben, gibt es einen Ort, an dem Sie von einem Typ in einen anderen konvertieren können. Und dieser Ort ist Aufgabe .

Variablen unterschiedlichen Typs können einander zugeordnet werden. Dabei wird der Wert einer Variablen eines Typs in einen Wert eines anderen Typs umgewandelt und der zweiten Variablen zugewiesen. In diesem Zusammenhang können wir zwei Arten der Typkonvertierung unterscheiden: Erweiterung und Verengung.

Eine Erweiterung ist wie das Verschieben eines Wertes von einem kleinen Korb in einen großen: Dieser Vorgang verläuft nahtlos und schmerzlos. Eine Verengung entsteht, wenn Sie einen Wert von einem großen Korb in einen kleinen verschieben: Möglicherweise ist nicht genügend Platz vorhanden und Sie müssen etwas wegwerfen.

Hier sind die Typen, sortiert nach Korbgröße:

Typumwandlung in Java 2


2. Erweiterungstypkonvertierungen

Oft ist es notwendig, eine Variable eines numerischen Typs einer Variablen eines anderen numerischen Typs zuzuweisen. Wie machst du das?

Java hat 4 Ganzzahltypen:

Typ Größe
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Variablen, die in kleineren Körben gespeichert sind, können immer Variablen zugewiesen werden, die in größeren Körben gespeichert sind.

int, shortund byteVariablen können einfach Variablen zugewiesen werden long. shortund byteVariablen können Variablen zugewiesen werden int. Und byteVariablen können Variablen zugewiesen werden short.

Beispiele:

Code Beschreibung
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Dieser Code lässt sich problemlos kompilieren.

Eine solche Konvertierung von einem kleineren zu einem größeren Typ wird als Erweiterungstypkonvertierung bezeichnet .

Was ist mit reellen Zahlen?

Bei ihnen ist alles beim Alten – auf die Größe kommt es an:

Typ Größe
float 4 bytes
double 8 bytes

floatdoubleVariablen können problemlos Variablen zugewiesen werden . Interessanter sieht es jedoch bei den Integer-Typen aus.

Sie können einer Variablen eine beliebige Ganzzahlvariable zuweisen float. Sogar der longTyp, der 8 Byte lang ist. Und Sie können floateiner Variablen alles zuweisen, was Sie wollen – jede ganzzahlige Variable oder Variable double:

Code Notiz
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Beachten Sie, dass die Konvertierung in einen echten Typ zu einem Genauigkeitsverlust führen kann, da nicht genügend signifikante Ziffern vorhanden sind.

Bei der Konvertierung von Ganzzahlen in Gleitkommazahlen können die niederwertigen Zahlenteile verworfen werden. Da aber unter Bruchzahlen Näherungswerte gespeichert werden, sind solche Zuweisungsoperationen zulässig.


3. Einschränkende Typkonvertierungen

Wie sieht es mit den anderen Möglichkeiten aus? longWas ist, wenn Sie einer Variablen einen Wert zuweisen müssen int?

Stellen Sie sich eine Variable als Korb vor. Wir haben Körbe in verschiedenen Größen: 1, 2, 4 und 8 Byte. Es ist kein Problem, Äpfel von einem kleineren Korb in einen größeren umzuladen. Beim Umstellen von einem größeren Korb in einen kleineren können jedoch einige Äpfel verloren gehen.

Diese Transformation – von einem größeren Typ zu einem kleineren Typ – wird als einschränkende Typkonvertierung bezeichnet . Bei der Durchführung einer solchen Zuweisungsoperation kann es sein, dass ein Teil einer Zahl einfach nicht in die neue Variable passt und daher verworfen wird.

Wenn wir einen Typ eingrenzen, müssen wir dem Compiler ausdrücklich mitteilen, dass wir keinen Fehler machen und absichtlich einen Teil der Zahl verwerfen. Hierzu wird der Typecast-Operator verwendet. Es handelt sich um einen Typnamen in Klammern .

In solchen Situationen verlangt der Java-Compiler , dass der Programmierer den Typecast-Operator angibt. Im Allgemeinen sieht es so aus:

(type) expression

Beispiele:

Code Beschreibung
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Der Typecast-Operator muss jeweils explizit angegeben werden

Hier aist gleich 1, und vielleicht scheint der Typecast-Operator übertrieben zu sein. Aber was wäre, wenn asie größer wären?

Code Beschreibung
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

Eine Million passt perfekt in ein longund in ein int. Wenn einer shortVariablen jedoch eine Million zugewiesen wird, werden die ersten beiden Bytes verworfen und nur die letzten beiden Bytes bleiben erhalten. Und bei der Zuweisung zu a bytebleibt nur das letzte Byte übrig.

So sind die Zahlen im Speicher angeordnet:

Typ Binäre Notation Dezimalschreibweise
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

charTyp

A charbelegt wie a shortzwei Bytes, aber um eines in ein anderes umzuwandeln, müssen Sie immer einen Typumwandlungsoperator verwenden. Das Problem hierbei ist, dass der Typ signiert ist und Werte von bis shortenthalten kann , der Typ jedoch ohne Vorzeichen ist und Werte von bis enthalten kann .-32,768+32,767char065,535

Negative Zahlen können nicht in einer gespeichert werden char, sie können jedoch in einer gespeichert werden short. Und a shortkann keine Zahlen speichern, die größer als sind 32,767, aber solche Zahlen können in a gespeichert werden char.


4. Art eines Ausdrucks

Was passiert, wenn Variablen unterschiedlichen Typs im selben Ausdruck verwendet werden? Logischerweise verstehen wir, dass sie zunächst in einen gemeinsamen Typ konvertiert werden müssen. Aber welcher?

Natürlich zum größeren.

Java konvertiert immer in den größeren Typ. Grob gesagt wird zunächst einer der Typen erweitert und erst dann wird die Operation mit Werten desselben Typs ausgeführt.

Wenn an intund a an einem Ausdruck beteiligt sind, wird longder Wert von in a konvertiert und erst dann wird die Operation fortgesetzt:intlong

Code Beschreibung
int a = 1;
long b = 2;
long c = a + b;
awird zu a erweitert longund dann erfolgt die Addition.

Gleitkommazahlen

Wenn in einem Ausdruck eine Ganzzahl und eine Gleitkommazahl ( floatoder double) beteiligt sind, wird die Ganzzahl in eine Gleitkommazahl ( floatoder double) umgewandelt und erst dann wird die Operation ausgeführt.

Wenn die Operation a floatund a umfasst, wird doubledas in a konvertiert . Was eigentlich erwartet wird.floatdouble

Überraschung

Die Typen byte, shortund charwerden immer in konvertiert, intwenn sie miteinander interagieren. Es gibt einen guten Grund, warum der intTyp als Standard-Integer-Typ gilt.

Wenn man a bytemit a multipliziert short, erhält man ein int. Wenn man a bytemit a multipliziert byte, erhält man ein int. Auch wenn man a byteund a hinzufügt byte, erhält man ein int.

Dafür gibt es mehrere Gründe. Beispiele:

Code Beschreibung
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120ist 13,200, was etwas größer als der Maximalwert des byteTyps ist:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120ist 230, was ebenfalls etwas größer als der Maximalwert des byteTyps ist:127

Wenn wir eine 8-Bit-Zahl (1 Byte) mit einer 8-Bit-Zahl (1 Byte) multiplizieren, erhalten wir im Allgemeinen eine Zahl, die 16 Bits (2 Bytes) belegt.

Dadurch werden alle Operationen mit Integer-Typen kleiner als intimmer sofort in s konvertiert int. intUnd das bedeutet, dass Sie den Typumwandlungsoperator immer explizit angeben müssen, wenn Sie das Ergebnis der Berechnung in einer Variablen eines Typs speichern möchten, der kleiner als ist .

Beispiele:

Code Beschreibung
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
Der byte * byteAusdruck wird ein seinint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
Der byte + byteAusdruck wird ein seinint
byte a = 1;
byte b = (byte) (a + 1);
Der byte + intAusdruck wird ein sein. int
Der wörtliche Ausdruck ist ein int.

5. Eine wichtige Nuance

Der Typecast-Operator hat eine ziemlich hohe Priorität.

Das heißt, wenn ein Ausdruck beispielsweise eine Addition und einen Typecast-Operator enthält, wird die Typecast vor der Addition durchgeführt.

Beispiel:

Code Beschreibung
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
Der Typecast-Operator wird nur auf die Variable angewendet a, die bereits eine ist byte. Dieser Code lässt sich nicht kompilieren.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Das ist der richtige Weg.

Wenn Sie den gesamten Ausdruck in einen bestimmten Typ konvertieren möchten und nicht nur eine Komponente des Ausdrucks, schließen Sie den gesamten Ausdruck in Klammern ein und setzen Sie den Typumwandlungsoperator voran.