Vesztes konverzió Java-ban

1. Áttekintés

Ebben a gyors bemutatóban megvitatjuk a veszteséges átalakítás fogalmát a Java-ban és annak okát.

Ugyanakkor néhány hasznos konverziós technikát is feltárunk a hiba elkerülése érdekében.

2. Vesztes konverzió

A vesztes konverzió egyszerűen az információ elvesztése az adatkezelés során.

A Java-ban megfelel a a változó értékének vagy pontosságának elvesztése konvertálás közben egyik típus a másikra.

Amikor megpróbálunk hozzárendelni egy változót nagy méretű típus kisebb méretű típusra, A Java hibát generál, inkompatibilis típusok: lehetséges veszteséges átalakítás, miközben összeállította a kódot.

Például próbáljunk meg hozzárendelni egy hosszú egy int:

hosszú hosszúNum = 10; int intNum = longNum;

A Java hibát bocsát ki a kód összeállításakor:

inkompatibilis típusok: lehetséges veszteséges átalakítás hosszúból int-be

Itt a Java megtalálja hosszú és int inkompatibilis és veszteséges konverziós hibát eredményez. Mert lehet hosszú értékeken kívül int -2 147 483 648 és 2 147 483 647 tartomány.

Hasonlóképpen próbáljunk meg hozzárendelni a úszó a hosszú:

float floatNum = 10.12f; hosszú longNum = floatNum;
inkompatibilis típusok: lehetséges veszteséges átalakítás úszóból hosszúra

Mint úszó lehetnek tizedesértékei, amelyeknek nincs megfelelő hosszú érték. Ezért ugyanazt a hibát fogjuk kapni.

Hasonlóképpen a kettős szám egy int ugyanazt a hibát fogja okozni:

dupla duplaNum = 1,2; int intNum = doubleNum;
inkompatibilis típusok: esetleges veszteséges átalakítás kettősből int

A kettős az értékek túl nagyok vagy túl kicsiek lehetnek egy int és a tizedesértékek elvesznek az átalakítás során. Ezért potenciálisan veszteséges konverzióról van szó.

Ezen hibába belefuthatunk egy egyszerű számítás végrehajtása közben is:

int fahrenheit = 100; int celcius = (fahrenheit - 32) * 5,0 / 9,0;

Amikor a kettős szorozzuk egy int, az eredményt a kettős. Következésképpen ez egy esetleges veszteséges átalakítás is.

Ezért a nem kompatibilis típusok a veszteséges konverziónak különböző mérete vagy típusa lehet (egész szám vagy tizedesjegy).

3. Primitív adattípusok

A Java-ban sok primitív adattípus érhető el a megfelelő burkolóosztályokkal.

Ezután állítsunk össze praktikus listát az összes lehetséges veszteséges konverzióról a Java-ban:

  • rövid nak nek byte vagy char
  • char nak nek byte vagy rövid
  • int nak nek byte, rövid vagy char
  • hosszú nak nek byte, rövid, char vagy int
  • úszó nak nek byte, rövid, char, int vagy hosszú
  • kettős nak nek byte, rövid, char, int, hosszú vagy úszó

Vegye figyelembe, hogy mégis rövid és char azonos méretűek legyenek. Még mindig, a konverzió rövid nak nek char veszteséges, mert char egy aláíratlan adattípus.

4. Átalakítási technikák

4.1. Konvertálás primitív típusok között

A primitívek átalakításának egyszerű módja a veszteséges átalakulás elkerülése érdekében a downcasting; más szavakkal, a nagyobb méretű típust kisebb méretűre öntve. Ezért a primitív átalakulás szűkülésének is nevezik.

Például konvertáljunk egy hosszú szám a-ig rövid downcasting segítségével:

hosszú hosszúNum = 24; rövid shortNum = (rövid) longNum; assertEquals (24, rövidNum);

Hasonlóképpen konvertáljuk a kettős egy int:

dupla duplaNum = 15,6; int integerNum = (int) doubleNum; assertEquals (15, integerNum);

Meg kell azonban jegyeznünk, hogy a túl nagy vagy túl kicsi értékű nagy méretű típus konvertálása kisebb méretűre downcasting révén váratlan értékeket eredményezhet.

Térjünk át hosszú tartományon kívül eső értékek rövid:

hosszú nagyLongNum = 32768; rövid minShortNum = (rövid) nagyLongNum; assertEquals (-32768, minShortNum); hosszú kisLongNum = -32769; rövid maxShortNum = (rövid) smallLongNum; assertEquals (32767, maxShortNum);

Ha alaposan elemezzük a konverziót, látni fogjuk, hogy ezek nem a várt értékek.

Más szavakkal, amikor a Java eléri a kis méretű típus legmagasabb értékét, miközben a nagy méretű típusból konvertál, a következő szám a legalacsonyabb érték kis méretű és fordítva.

Értsük meg ezt példákon keresztül. Mikor nagyHosszúNum 32768 értékkel átszámítva rövid, az értéke shortNum1 -32768. Mivel a max értéke rövid értéke 32767, ezért a Java a rövid.

Hasonlóképpen, mikor smallLongNum konvertálódik rövid. Az értéke shortNum2 32767, mivel a Java a következő maximális értékre megy rövid.

Lássuk azt is, hogy mi történik, ha az a max és min értékét konvertáljuk hosszú egy int:

long maxLong = Long.MAX_VALUE; int minInt = (int) maxLong; assertEquals (-1, minInt); hosszú minLong = Long.MIN_VALUE; int maxInt = (int) minLong; assertEquals (0, maxInt);

4.2. Átalakítás a burkoló objektumok és a primitív típusok között

A burkolóobjektum primitívvé történő közvetlen átalakításához különféle módszereket használhatunk a burkolóosztályokban, mint pl intValue (), shortValue () és longValue (). Ezt úgy hívják kicsomagolás.

Konvertáljuk például a Úszó kifogásolni a hosszú:

Float floatNum = 17.564f; long longNum = floatNum.longValue (); assertEquals (17, longNum);

Továbbá, ha megnézzük a longValue vagy hasonló módszerek esetén megtaláljuk a szűkítő primitív konverzió alkalmazását:

public long longValue () {return (long) value; }

Időnként azonban el kell kerülni a primitív átalakulás szűkülését az értékes információk mentése érdekében:

Dupla duplaNum = 15,9999; long longNum = doubleNum.longValue (); assertEquals (15, longNum); 

Konvertálás után a longNum lesz 15. Azonban a doubleNum 15,9999, ami nagyon közel van a 16-hoz.

Ehelyett használhatjuk Math.round () a legközelebbi egész számra való átváltáshoz:

Dupla duplaNum = 15,9999; long longNum = Matematikai kör (doubleNum); assertEquals (16, longNum);

4.3. Átalakítás burkoló objektumok között

Ehhez használjuk a már tárgyalt átalakítási technikákat.

Először áttérünk burkolóobjektumot primitív értékre, lecsökkentse és átalakítsa egy másik burkolóobjektummá. Más szavakkal, kicsomagolást, lefejtést és bokszolási technikákat fogunk végrehajtani.

Konvertáljuk például a Kettős kifogásolni egy Egész szám tárgy:

Dupla duplaNum = 10,3; dupla dbl = doubleNum.doubleValue (); // unboxing int intgr = (int) dbl; // Integer intNum = Integer.valueOf (intgr); assertEquals (Integer.valueOf (10), intNum); 

Végül használjuk Egész szám.értéke() hogy átalakítsa a primitív típust int egy Egész szám tárgy. Ezt a típusú átalakítást hívják ökölvívás.

5. Következtetés

Ebben a cikkben számos példa segítségével feltártuk a veszteséges átalakítás fogalmát a Java-ban. Ezen felül összeállítottunk egy praktikus listát az összes lehetséges veszteséges konverzióról is.

Útközben a primitív konverzió szűkítését azonosítottuk egyszerű módszerként a primitív számok konvertálására és a veszteséges konverziós hibák elkerülésére.

Ugyanakkor további hasznos technikákat is feltártunk a Java-ban történő numerikus konverziókra.

A cikk kód implementációi a GitHub oldalon találhatók.