1. Típusírás
A primitív típusú változók (a típus kivételével boolean
) különféle típusú számok tárolására szolgálnak. Bár a változók típusai soha nem változtak, van egy hely, ahol egyik típusról a másikra konvertálhat. És ez a hely megbízás .
Különböző típusú változók rendelhetők egymáshoz. Amikor ezt megteszi, az egyik típusú változó értéke egy másik típusú értékké alakul, és a második változóhoz rendelődik. Ebből a szempontból kétféle típuskonverziót különböztethetünk meg: a szélesítést és a szűkítést.
A szélesítés olyan, mintha egy értéket egy kis kosárból egy nagyba mozgatnánk: ez a művelet zökkenőmentes és fájdalommentes. Szűkítés akkor következik be, amikor egy értéket egy nagy kosárból egy kicsibe helyez át: előfordulhat, hogy nincs elég hely, és valamit ki kell dobnia.
Íme a típusok kosárméret szerint rendezve:
2. Típuskonverziók szélesítése
Gyakran szükséges egy numerikus típusú változót egy másik numerikus típusú változóhoz rendelni. Hogyan csinálod, hogy?
A Java-nak 4 egész típusa van:
típus | Méret |
---|---|
byte |
1 byte |
short |
2 bytes |
int |
4 bytes |
long |
8 bytes |
A kisebb kosarakban tárolt változókat mindig hozzá lehet rendelni a nagyobb kosarakban tárolt változókhoz.
int
, short
és byte
a változók könnyen hozzárendelhetők long
a változókhoz. short
változókhoz pedig változók byte
rendelhetők int
. A változókhoz pedig byte
hozzá lehet rendelni short
a változókat.
Példák:
Kód | Leírás |
---|---|
|
Ez a kód jól lefordítható. |
Az ilyen átalakítást, kisebbről nagyobbra, szélesítő típusú átalakításnak nevezzük.
Mi a helyzet a valós számokkal?
Velük minden ugyanaz – a méret számít:
típus | Méret |
---|---|
float |
4 bytes |
double |
8 bytes |
float
double
a változókat probléma nélkül hozzá lehet rendelni a változókhoz. De a dolgok érdekesebbek az egész típusokkal.
Egy változóhoz bármilyen egész változót hozzárendelhet float
. Még a long
típus is, ami 8 bájt hosszú. És bármit hozzárendelhet float
egy változóhoz – bármilyen egész számot vagy változót double
:
Kód | jegyzet |
---|---|
|
|
Ne feledje, hogy a valós típusra való átalakítás a pontosság elvesztésével járhat, mivel nincs elegendő jelentős számjegy.
Egész számokról lebegőpontos számokká konvertálásakor a számok alacsonyabb rendű részei elvethetők. De mivel a törtszámok hozzávetőleges értékeket tárolnak, az ilyen hozzárendelési műveletek megengedettek.
3. Szűkítő típuskonverziók
Mi a helyzet a többi lehetőséggel? Mi van, ha értéket kell rendelnie long
egy int
változóhoz?
Képzelj el egy változót kosárként. Különféle méretű kosaraink vannak: 1, 2, 4 és 8 bájtos. Nem probléma, ha egy kisebb kosárból almát teszünk át egy nagyobbba. Ha azonban nagyobb kosárról kisebbre vált, az alma egy része elveszhet.
Ezt az átalakítást – nagyobb típusból kisebb típusba – szűkítő típusú konverziónak nevezzük . Egy ilyen hozzárendelési művelet végrehajtásakor előfordulhat, hogy egy szám egy része egyszerűen nem fér bele az új változóba, és ezért eldobható.
Egy típus szűkítésekor kifejezetten jelezni kell a fordítónak, hogy nem hibázunk, szándékosan eldobjuk a szám egy részét. Ehhez a typecast operátort használjuk. Ez egy zárójelben lévő típusnév .
Ilyen helyzetekben a Java fordító megköveteli a programozótól a typecast operátor megadását. Általában így néz ki:
(type) expression
Példák:
Kód | Leírás |
---|---|
|
A typecast operátort minden alkalommal kifejezetten fel kell tüntetni |
Itt a
egyenlő a -val 1
, és talán a typecast operátor túlzásnak tűnik. De mi lenne, ha a
nagyobb lenne?
Kód | Leírás |
---|---|
|
|
Egymillió tökéletesen belefér egy long
és egy int
. De ha egy milliót hozzárendel egy változóhoz short
, az első két bájt eldobásra kerül, és csak az utolsó két bájt marad meg. És amikor hozzárendel egy byte
, csak az utolsó bájt marad meg.
A számok elrendezése a memóriában:
típus | Bináris jelölés | Tizedes jelölés |
---|---|---|
int |
0b 00000000 00001111 01000010 01000000 | 1000000 |
short |
0b 01000010 01000000 | 16.960 |
byte |
0b 01000000 | 64 |
char
típus
Az A char
, akárcsak a short
, két bájtot foglal el, de az egyik konvertálásához mindig egy typecast operátort kell használnia. A probléma itt az, hogy a short
típus előjeles, és tartalmazhat értékeket -tól -32,768
-ig +32,767
, de a char
típus előjel nélküli, és tartalmazhat -tól 0
-ig értékeket 65,535
.
Negatív számok nem tárolhatók a -ban char
, de tárolhatók egy -ben short
. És a short
nem tárolhat nagyobb számokat, mint 32,767
, de ilyen számok tárolhatók a -ban char
.
4. Kifejezés típusa
Mi van akkor, ha különböző típusú változókat használunk ugyanabban a kifejezésben? Logikusan értjük, hogy először át kell alakítani egy közös típusba. De melyiket?
Természetesen a nagyobbra.
A Java mindig nagyobb típusra konvertál. Nagyjából az egyik típust először kiszélesítjük, és csak ezután hajtjuk végre a műveletet azonos típusú értékekkel.
Ha egy int
és a long
részt vesz egy kifejezésben, akkor az értéke int
a-ra lesz konvertálva long
, és csak ezután folytatódik a művelet:
Kód | Leírás |
---|---|
|
a ki lesz szélesítve a-ra long , majd megtörténik a hozzáadás. |
Lebegőpontos számok
Ha egy egész szám és egy lebegőpontos szám ( float
vagy double
) szerepel egy kifejezésben, akkor az egész számot lebegőpontos számmá ( float
vagy double
) alakítja át, és csak ezután hajtja végre a műveletet.
Ha a műveletben a float
és a szerepel double
, akkor az a float
lesz átalakítva double
. Ami tulajdonképpen várható is.
A byte
, short
, és char
típusok mindig konvertálódnak egymásra, int
amikor interakcióba lépnek egymással. Jó oka van annak, hogy miért int
tekintik a típust a szabványos egész típusnak.
Ha az a-t megszorozod a byte
-val short
, akkor egy int
. Ha az a-t megszorozod a byte
-val byte
, akkor egy int
. Még ha hozzáad egy -t byte
és egy -t byte
, akkor is kap egy -ot int
.
Ennek több oka is van. Példák:
Kód | Leírás |
---|---|
|
110 * 120 , ami 13,200 valamivel nagyobb, mint a byte típus maximális értéke:127 |
|
110 + 120 , ami 230 szintén valamivel nagyobb, mint a byte típus maximális értéke:127 |
Általában, ha egy 8 bites (1 bájt) számot megszorozunk egy 8 bites (1 bájt) számmal, olyan számot kapunk, amely 16 bites bitet (2 bájt) foglal el.
Ennek eredményeként az összes olyan művelet, amelyik kisebb egész típusú, mint int
mindig, azonnal s-re konvertálódik int
. Ez pedig azt jelenti, hogy ha a számítás eredményét egy olyan változóban szeretné tárolni, amely kisebb, mint egy int
, akkor mindig kifejezetten meg kell adnia a typecast operátort.
Példák:
Kód | Leírás |
---|---|
|
A byte * byte kifejezés egy leszint |
|
A byte + byte kifejezés egy leszint |
|
A byte + int kifejezés egy lesz int A szó szerinti egy int . |
5. Fontos árnyalat
A typecast operátornak meglehetősen magas prioritása van.
Ez azt jelenti, hogy ha egy kifejezés tartalmaz például összeadást és typecast operátort, akkor a typecast az összeadás előtt kerül végrehajtásra.
Példa:
Kód | Leírás |
---|---|
|
A typecast operátor csak arra a változóra kerül alkalmazásra a , amely már egy byte . Ez a kód nem fordítható le. |
|
Ez a helyes út. |
Ha a teljes kifejezést egy adott típusra szeretné konvertálni, és nem csak a kifejezés egy összetevőjét, akkor tegye zárójelbe a teljes kifejezést, és tegye a typecast operátort elé.