CodeGym /Java blog /Véletlen /Primitív típusok szélesítése és szűkítése
John Squirrels
Szint
San Francisco

Primitív típusok szélesítése és szűkítése

Megjelent a csoportban
Szia! Ahogy haladtál a CodeGymben, sokszor találkoztál primitív típusokkal. Íme egy rövid lista, amit tudunk róluk:
  1. Nem objektumok, és a memóriában tárolt értéket képviselik
  2. Több fajta létezik
    • Egész számok: byte , short , int , long
    • Lebegőpontos (tört) számok: lebegő és dupla
    • Logikai értékek: logikai érték
    • Szimbolikus értékek (betűk és számok ábrázolásához): char
  3. Minden típusnak megvan a maga értéktartománya:

Primitív típus Méret a memóriában Értéktartomány
byte 8 bites -128-127
rövid 16 bites -32768-32767
char 16 bites 0-tól 65536-ig
int 32 bites -2147483648-2147483647
hosszú 64 bites -9223372036854775808-9223372036854775807
úszó 32 bites (2 -149 hatványához) ((2 - (2 -23 hatványához)) * 2 127 hatványához)
kettős 64 bites (-2 a 63 hatványához) - ((2 a 63 hatványához) - 1)
logikai érték 8 (ha tömbökben használja), 32 (ha nem tömbben használja) igaz vagy hamis
De amellett, hogy különböző értékekkel rendelkeznek, abban is különböznek, hogy mekkora helyet foglalnak el a memóriában. Egy int több mint egy bájt. És a hosszú nagyobb, mint a rövid. A primitívek által elfoglalt memória mennyisége az orosz fészkelő babákéhoz hasonlítható: A primitív típusok szélesítése és szűkítése - 2 minden fészkelő babában van szabad hely. Minél nagyobb a fészekbaba, annál több hely van benne. Egy nagy fészkelő baba ( hosszú ) könnyen elfér egy kisebb int . Könnyen illeszkedik, és nem kell mást tennie. A Java-ban, amikor primitívekkel dolgozik, ezt implicit konverziónak nevezik. Vagy másképp fogalmazva, ezt szélesítésnek hívják.

Bővítés Java nyelven

Íme egy egyszerű példa a szélesítő konverzióra:

public class Main {

   public static void main(String[] args) {
      
       int bigNumber = 10000000;

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
Itt egy bájt értéket rendelünk egy int változóhoz. A hozzárendelés minden probléma nélkül sikerül: az egy bájtban tárolt érték kevesebb memóriát foglal, mint amennyit egy int képes befogadni. A kis fészkelő baba (byte érték) könnyen elfér a nagy fészkelő baba belsejében ( int változó). Más kérdés, ha az ellenkezőjét próbáljuk meg tenni, azaz nagy értéket tenni egy olyan változóba, amelynek tartománya nem fér el ekkora adattípussal. Az igazi fészkelő babáknál a szám egyszerűen nem férne el. Java-val lehet, de árnyalatokkal. Próbáljunk meg egy int-et beilleszteni egy rövid változóba:

public static void main(String[] args) {

   int bigNumber = 10000000;
  
   short littleNumber = 1000;

   littleNumber = bigNumber;// Error!
   System.out.println(bigNumber);
}
Hiba! A fordító megérti, hogy valami rendelleneset akarsz tenni azzal, hogy egy nagy fészkelő babát ( int ) egy kicsi ( rövid ) belsejébe tolsz. Ebben az esetben a fordítási hiba a fordító figyelmeztetése: "Hé, teljesen biztos benne , hogy ezt akarja?" Ha biztos vagy benne, akkor mondd meg a fordítónak: "Minden rendben van. Tudom, mit csinálok!" Ezt a folyamatot explicit típuskonverziónak vagy szűkítésnek nevezik.

Szűkítés Java-ban

Szűkítő konverzió végrehajtásához kifejezetten meg kell adnia azt a típust, amelyre át szeretné konvertálni az értéket. Más szavakkal, válaszolnia kell a fordító kérdésére: "Nos, melyik kis fészkelő babába szeretnéd beletenni ezt a nagy fészkelő babát?" A mi esetünkben ez így néz ki:

public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
Kifejezetten jelezzük, hogy egy int-et szeretnénk beilleszteni egy rövid változóba, és vállaljuk a felelősséget. Látva, hogy egy szűkebb típust kifejezetten jeleztek, a fordító végrehajtja az átalakítást. mi az eredmény? Konzol kimenet: -27008 Ez egy kicsit váratlan volt. Miért pont ezt kaptuk? Valójában minden nagyon egyszerű. Eredetileg az érték 10000000 volt. Egy int változóban tárolták , ami 32 bitet foglal el. Ez a bináris ábrázolása:
A primitív típusok szélesítése és szűkítése - 3
Ezt az értéket egy rövid változóba írjuk , amely csak 16 bitet tud tárolni! Ennek megfelelően a számunknak csak az első 16 bitje kerül át oda. A többit eldobjuk. Ennek eredményeként a rövid változó a következő értéket kapja
A primitív típusok szélesítése és szűkítése - 4
ami decimális formában egyenlő a -27008-cal. Ezért a fordító kéri a "megerősítést" azáltal, hogy egy konkrét típusra szűkítő konverziót jelez. Először is ez azt mutatja, hogy felelősséget vállal az eredményért. Másodszor pedig megmondja a fordítónak, hogy mennyi helyet kell lefoglalnia a konvertálás során. Végül is, az utolsó példában, ha egy bájtváltozóhoz int értéket rendelnénk, nem pedig shorthoz , akkor csak 8 bit állna rendelkezésünkre, nem 16, és az eredmény más lenne. A tört típusoknak ( lebegő és dupla ) saját folyamatuk van a konverziók szűkítésére. Ha megpróbál egy frakciószámot egész típusúra önteni, a tört részt elveti.

public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
Konzol kimenet: 2

char

Már tudja, hogy a char az egyes karakterek megjelenítésére szolgál.

public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';
  
}
Ennek az adattípusnak azonban számos olyan jellemzője van, amelyeket fontos megérteni. Nézzük újra az értéktartományok táblázatát:
Primitív típus Méret a memóriában Értéktartomány
byte 8 bites -128-127
rövid 16 bites -32768-32767
char 16 bites 0-tól 65536-ig
int 32 bites -2147483648-2147483647
hosszú 64 bites -9223372036854775808-9223372036854775807
úszó 32 bites (2 -149 hatványához) ((2 - (2 -23 hatványához)) * 2 127 hatványához)
kettős 64 bites (-2 a 63 hatványához) - ((2 a 63 hatványához) - 1)
logikai érték 8 (ha tömbökben használja), 32 (ha nem tömbben használja) igaz vagy hamis
A 0 és 65536 közötti tartomány a char típusra vonatkozik . De mit jelent ez? Hiszen a char nem csak számokat jelent, hanem betűket, írásjeleket is... A helyzet az, hogy a Java-ban a karakterek értékei Unicode formátumban vannak tárolva. Az egyik előző leckében már találkoztunk a Unicode-dal. Valószínűleg emlékszel arra, hogy az Unicode egy karakterkódolási szabvány, amely a világ szinte összes írott nyelvének szimbólumait tartalmazza. Más szóval, ez egy olyan speciális kódok listája, amelyek szinte minden karaktert képviselnek bármilyen nyelven. Az egész Unicode-tábla nagyon nagy, és természetesen nem kell fejből megtanulni. Íme egy kis részlet belőle: A primitív típusok szélesítése és szűkítése - 5 A legfontosabb dolog az, hogy megértsük a karakterek tárolását, és ne feledjük, hogy ha ismerjük egy adott karakter kódját, mindig elő tudjuk állítani azt a karaktert a programunkban. Próbáljuk meg egy véletlen számmal:

public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
Konzol kimenet: 耰 Ez a karakterek Java-ban való tárolására használt formátum . Minden szimbólum egy számnak felel meg: egy 16 bites (két byte-os) numerikus kódnak. Az Unicode-ban a 32816 a 耰 kínai karakternek felel meg. Jegyezze fel a következő pontot. Ebben a példában egy int változót használtunk . 32 bitet foglal el a memóriában, míg egy karakter 16-ot. Itt egy int -et választottunk , mert a számunk (32816) nem fér bele egy shortba . Bár a char mérete (csakúgy, mint a short ) 16 bit, a char tartományban nincsenek negatív számok , így a char "pozitív" részea tartomány kétszer nagyobb (65536 a rövid típus 32767 helyett ). Használhatunk int-et mindaddig, amíg a kódunk 65536 alatt marad. De ha 65536-nál nagyobb int értéket hoz létre, akkor az több mint 16 bitet foglal el. Ez pedig szűkülő konverziót fog eredményezni

char c = (char) x;
az extra bitek el lesznek dobva (ahogy fentebb tárgyaltuk), és az eredmény egészen váratlan lesz.

Karakterek és egész számok hozzáadásának speciális jellemzői

Nézzünk egy szokatlan példát:

public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i + c);
   }
}
Konzol kimenet: 50 O_О Mi értelme van ennek? 1+1. Honnan jött az 50?! Már tudja, hogy charaz értékek a memóriában 0 és 65536 közötti számokként vannak tárolva, és hogy ezek a számok egy karakter Unicode-beli reprezentációi. A primitív típusok szélesítése és szűkítése - 6 Ha hozzáadunk egy karaktert és valamilyen egész számtípust, a karakter a megfelelő Unicode számmá alakul. Kódunkban, amikor hozzáadtuk az 1-et és az '1-et, az '1' szimbólumot a saját kódjára alakítottuk át, ami 49 (ezt a fenti táblázatban ellenőrizheti). Ezért az eredmény 50. Vegyük még egyszer példaként régi barátunkat 耰, és próbáljuk meg hozzáadni valamelyik számhoz.

public static void main(String[] args) {

   char c = '耰';
   int x = 200;

   System.out.println(c + x);
}
Konzol kimenet: 33016 Már rájöttünk, hogy a 耰 32816-nak felel meg. És ha ezt a számot és 200-at összeadjuk, akkor a következő eredményt kapjuk: 33016. :) Mint látható, itt az algoritmus meglehetősen egyszerű, de nem szabad elfelejteni .
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION