Hallo! Während Sie CodeGym durchgearbeitet haben, sind Sie oft auf primitive Typen gestoßen. Hier ist eine kurze Liste dessen, was wir über sie wissen:
- Sie sind keine Objekte und stellen einen im Speicher gespeicherten Wert dar
- Es gibt verschiedene Arten
- Ganze Zahlen: Byte , Short , Int , Long
- Gleitkommazahlen (Bruchzahlen): Float und Double
- Logische Werte: boolesch
- Symbolische Werte (zur Darstellung von Buchstaben und Ziffern): char
-
Jeder Typ hat seinen eigenen Wertebereich:
Primitiver Typ |
Größe im Speicher |
Wertebereich |
Byte |
8 Bit |
-128 bis 127 |
kurz |
16 Bit |
-32768 bis 32767 |
verkohlen |
16 Bit |
0 bis 65536 |
int |
32 Bit |
-2147483648 bis 2147483647 |
lang |
64 Bit |
-9223372036854775808 bis 9223372036854775807 |
schweben |
32 Bit |
(2 hoch -149) bis ((2 - (2 hoch -23)) * 2 hoch 127) |
doppelt |
64 Bit |
(-2 hoch 63) bis ((2 hoch 63) - 1) |
Boolescher Wert |
8 (bei Verwendung in Arrays), 32 (wenn nicht in Arrays verwendet) |
richtig oder falsch |
Sie haben aber nicht nur unterschiedliche Werte, sondern unterscheiden sich auch darin, wie viel Platz sie im Speicher beanspruchen. Ein
int benötigt mehr als ein Byte. Und ein
Long ist größer als ein Short. Der Speicherbedarf von Primitiven kann mit russischen Nistpuppen verglichen werden:
![Erweiterung und Verengung primitiver Typen - 2]()
In jeder Nistpuppe ist Platz vorhanden. Je größer die Nistpuppe, desto mehr Platz ist vorhanden. Eine große Nistpuppe (
lang ) bietet problemlos Platz für eine kleinere
Puppe . Es passt problemlos und Sie müssen nichts weiter tun. In Java wird dies bei der Arbeit mit Grundelementen als implizite Konvertierung bezeichnet. Oder anders ausgedrückt: Es heißt Verbreiterung.
Erweiterung in Java
Hier ist ein einfaches Beispiel für eine Erweiterungskonvertierung:
public class Main {
public static void main(String[] args) {
int bigNumber = 10000000;
byte littleNumber = 16;
bigNumber = littleNumber;
System.out.println(bigNumber);
}
}
Hier weisen wir einer int- Variablen einen Bytewert zu . Die Zuweisung gelingt problemlos: Der in einem Byte gespeicherte Wert beansprucht weniger Speicher, als ein
int aufnehmen kann. Die kleine Nistpuppe (Bytewert) passt problemlos in die große Nistpuppe (
int- Variable). Anders verhält es sich, wenn Sie das Gegenteil versuchen, also einen großen Wert in eine Variable eingeben, deren Bereich einen so großen Datentyp nicht aufnehmen kann. Bei echten Nistpuppen würde die Anzahl einfach nicht passen. Mit Java ist das möglich, allerdings mit Nuancen. Versuchen wir, ein
int in eine
kurze Variable einzufügen:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = bigNumber;// Error!
System.out.println(bigNumber);
}
Fehler! Der Compiler versteht, dass Sie versuchen, etwas Ungewöhnliches zu tun, indem Sie eine große Nistpuppe (
int ) in eine kleine (
short ) schieben. In diesem Fall ist der Kompilierungsfehler eine Warnung des Compilers: „Hey, sind Sie
absolut sicher , dass Sie das tun möchten?“ Wenn Sie sicher sind, sagen Sie dem Compiler:
„Alles ist in Ordnung. Ich weiß, was ich tue!“ Dieser Vorgang wird als explizite Typkonvertierung oder Eingrenzung bezeichnet.
Einengung in Java
Um eine einschränkende Konvertierung durchzuführen, müssen Sie explizit den Typ angeben, in den Sie Ihren Wert konvertieren möchten. Mit anderen Worten, Sie müssen die Frage des Compilers beantworten:
„Nun, in welche dieser kleinen Nistpuppen möchten Sie diese große Nistpuppe stecken?“ In unserem Fall sieht es so aus:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = (short) bigNumber;
System.out.println(littleNumber);
}
Wir weisen ausdrücklich darauf hin, dass wir ein int in eine
kurze Variable einfügen möchten und dass wir die Verantwortung dafür übernehmen. Da explizit ein engerer Typ angegeben wurde, führt der Compiler die Konvertierung durch. Was ist das Ergebnis? Konsolenausgabe:
-27008
Das war etwas unerwartet. Warum genau haben wir das bekommen? Eigentlich ist alles ganz einfach.
Ursprünglich war der Wert 10000000. Er wurde in einer int- Variablen gespeichert , die 32 Bit belegt. Dies ist seine binäre Darstellung:
Diesen Wert schreiben wir in eine
kurze Variable, die nur 16 Bit speichern kann! Dementsprechend werden nur die ersten 16 Bits unserer Zahl dorthin verschoben. Der Rest wird verworfen. Als Ergebnis erhält die kurze Variable den folgenden Wert
was in Dezimalform gleich -27008 ist. Aus diesem Grund fordert der Compiler Sie zur „Bestätigung“ auf, indem er eine explizite einschränkende Konvertierung auf einen bestimmten Typ angibt. Dies zeigt zunächst einmal, dass Sie die Verantwortung für das Ergebnis übernehmen. Und zweitens teilt es dem Compiler mit, wie viel Speicherplatz bei der Konvertierung zugewiesen werden soll. Denn wenn wir im letzten Beispiel einer Byte-Variablen einen int-Wert statt einem
short zuweisen würden, dann stünden uns nur 8 Bits zur Verfügung, nicht 16, und das Ergebnis wäre anders. Bruchtypen (
float und
double ) verfügen über einen eigenen Prozess zur Eingrenzung von Konvertierungen. Wenn Sie versuchen, eine Bruchzahl in einen Ganzzahltyp umzuwandeln, wird der Bruchteil verworfen.
public static void main(String[] args) {
double d = 2.7;
long x = (int) d;
System.out.println(x);
}
Konsolenausgabe:
2
verkohlen
Sie wissen bereits, dass
char zur Anzeige einzelner Zeichen verwendet wird.
public static void main(String[] args) {
char c = '!';
char z = 'z';
char i = '8';
}
Dieser Datentyp weist jedoch mehrere Merkmale auf, die es zu verstehen gilt. Schauen wir uns noch einmal die Tabelle der Wertebereiche an:
Primitiver Typ |
Größe im Speicher |
Wertebereich |
Byte |
8 Bit |
-128 bis 127 |
kurz |
16 Bit |
-32768 bis 32767 |
verkohlen |
16 Bit |
0 bis 65536 |
int |
32 Bit |
-2147483648 bis 2147483647 |
lang |
64 Bit |
-9223372036854775808 bis 9223372036854775807 |
schweben |
32 Bit |
(2 hoch -149) bis ((2 - (2 hoch -23)) * 2 hoch 127) |
doppelt |
64 Bit |
(-2 hoch 63) bis ((2 hoch 63) - 1) |
Boolescher Wert |
8 (bei Verwendung in Arrays), 32 (wenn nicht in Arrays verwendet) |
richtig oder falsch |
Für den Char- Typ wird der Bereich 0 bis 65536 angegeben . Aber was bedeutet das? Schließlich stellt ein
Zeichen nicht nur Zahlen dar, sondern auch Buchstaben, Satzzeichen usw. Die Sache ist, dass in Java
Zeichenwerte im Unicode-Format gespeichert werden. Wir sind Unicode bereits in einer der vorherigen Lektionen begegnet. Sie erinnern sich wahrscheinlich daran, dass Unicode ein Zeichenkodierungsstandard ist, der die Symbole fast aller Schriftsprachen der Welt enthält. Mit anderen Worten handelt es sich um eine Liste spezieller Codes, die nahezu jedes Zeichen in jeder Sprache darstellen. Die gesamte Unicode-Tabelle ist sehr umfangreich und es besteht natürlich keine Notwendigkeit, sie auswendig zu lernen. Hier ein kleiner Ausschnitt davon:
![Erweiterung und Verengung primitiver Typen - 5]()
Das Wichtigste ist, zu verstehen, wie Zeichen gespeichert werden, und sich daran zu erinnern, dass Sie dieses Zeichen jederzeit in Ihrem Programm erzeugen können, wenn Sie den Code für ein bestimmtes Zeichen kennen. Versuchen wir es mit einer Zufallszahl:
public static void main(String[] args) {
int x = 32816;
char c = (char) x ;
System.out.println(c);
}
Konsolenausgabe: Dies ist das Format, das zum Speichern von
Zeichen in Java verwendet wird. Jedes Symbol entspricht einer Zahl: einem 16-Bit-Zahlencode (zwei Bytes). In Unicode entspricht 32816 dem chinesischen Zeichen 耰. Beachten Sie den folgenden Punkt. In diesem Beispiel haben wir eine
int- Variable verwendet. Es belegt 32 Bit im Speicher, während ein
Zeichen 16 Bits belegt. Hier haben wir ein
int gewählt , da unsere Zahl (32816) nicht in ein
short passt . Obwohl die Größe eines
char (genau wie ein
short ) 16 Bit beträgt, gibt es im
char- Bereich, also im „positiven“ Teil des
char , keine negativen ZahlenDie Reichweite ist doppelt so groß (65536 statt 32767 beim
kurzen Typ). Wir können ein
int verwenden , solange unser Code unter 65536 bleibt. Wenn Sie jedoch einen
int- Wert größer als 65536 erstellen, belegt dieser mehr als 16 Bit. Und dies wird zu einer einschränkenden Konvertierung führen
char c = (char) x;
Die zusätzlichen Bits werden verworfen (wie oben beschrieben) und das Ergebnis wird ziemlich unerwartet sein.
Besonderheiten beim Hinzufügen von Zeichen und Ganzzahlen
Schauen wir uns ein ungewöhnliches Beispiel an:
public class Main {
public static void main(String[] args) {
char c = '1';
int i = 1;
System.out.println(i + c);
}
}
Konsolenausgabe:
50
O_О
Wie macht das Sinn? 1+1. Woher kommen die 50?! Sie wissen bereits, dass
char
Werte im Speicher als Zahlen im Bereich von 0 bis 65536 gespeichert werden und dass diese Zahlen eine Unicode-Darstellung eines Zeichens sind.
![Erweiterung und Verengung primitiver Typen - 6]()
Wenn wir ein
Zeichen und einen Ganzzahltyp hinzufügen, wird das
Zeichen in die entsprechende Unicode-Zahl konvertiert. Als wir in unserem Code 1 und „1“ addierten, wurde das Symbol „1“ in seinen eigenen Code umgewandelt, der 49 ist (Sie können dies in der Tabelle oben überprüfen). Daher ist das Ergebnis 50. Nehmen wir noch einmal unseren alten Freund 耰 als Beispiel und versuchen, ihn zu einer Zahl zu addieren.
public static void main(String[] args) {
char c = '耰';
int x = 200;
System.out.println(c + x);
}
Konsolenausgabe:
33016
Wir haben bereits herausgefunden, dass 耰 32816 entspricht. Und wenn wir diese Zahl und 200 addieren, erhalten wir unser Ergebnis: 33016. :) Wie Sie sehen, ist der Algorithmus hier recht einfach, aber Sie sollten ihn nicht vergessen .
GO TO FULL VERSION