Szia! Ahogy haladtál a CodeGymben, sokszor találkoztál primitív típusokkal. Íme egy rövid lista, amit tudunk róluk:
- Nem objektumok, és a memóriában tárolt értéket képviselik
- 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
-
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ó:
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;
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:
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
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 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
char
az é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.
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 .