1. Típusírás

Typecasting Java nyelven

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:

Typecasting Java 2-ben


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 bytea változók könnyen hozzárendelhetők longa változókhoz. shortváltozókhoz pedig változók byterendelhetők int. A változókhoz pedig bytehozzá lehet rendelni shorta változókat.

Példák:

Kód Leírás
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
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

floatdoublea 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 longtípus is, ami 8 bájt hosszú. És bármit hozzárendelhet floategy változóhoz – bármilyen egész számot vagy változót double:

Kód jegyzet
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

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 longegy intvá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
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
A typecast operátort minden alkalommal kifejezetten fel kell tüntetni

Itt aegyenlő a -val 1, és talán a typecast operátor túlzásnak tűnik. De mi lenne, ha anagyobb lenne?

Kód Leírás
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

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

chartí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 shorttípus előjeles, és tartalmazhat értékeket -tól -32,768-ig +32,767, de a chartí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 shortnem 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 longrészt vesz egy kifejezésben, akkor az értéke inta-ra lesz konvertálva long, és csak ezután folytatódik a művelet:

Kód Leírás
int a = 1;
long b = 2;
long c = a + b;
aki 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 ( floatvagy double) szerepel egy kifejezésben, akkor az egész számot lebegőpontos számmá ( floatvagy 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 floatlesz átalakítva double. Ami tulajdonképpen várható is.

Meglepetés

A byte, short, és chartípusok mindig konvertálódnak egymásra, intamikor interakcióba lépnek egymással. Jó oka van annak, hogy miért inttekintik 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
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120, ami 13,200valamivel nagyobb, mint a bytetípus maximális értéke:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120, ami 230szintén valamivel nagyobb, mint a bytetí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 intmindig, 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
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
A byte * bytekifejezés egy leszint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
A byte + bytekifejezés egy leszint
byte a = 1;
byte b = (byte) (a + 1);
A byte + intkifejezé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
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
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.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
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é.