CodeGym /Java-Blog /Random-DE /Erweiterung und Verengung primitiver Typen
Autor
Aditi Nawghare
Software Engineer at Siemens

Erweiterung und Verengung primitiver Typen

Veröffentlicht in der Gruppe Random-DE
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:
  1. Sie sind keine Objekte und stellen einen im Speicher gespeicherten Wert dar
  2. 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
  3. 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:
Erweiterung und Verengung primitiver Typen - 3
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
Erweiterung und Verengung primitiver Typen - 4
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 charWerte 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 .
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION