Stratová konverzia v Jave

1. Prehľad

V tomto rýchlom výučbe sa budeme zaoberať konceptom stratovej konverzie v Jave a dôvodmi, ktoré ju vedú.

Zároveň preskúmame niektoré užitočné techniky prevodu, aby sme sa tejto chybe vyhli.

2. Stratová premena

Stratová konverzia je jednoducho strata informácií pri spracovaní údajov.

V Jave to zodpovedá možnosti strata hodnoty alebo presnosti premennej pri konverzii jeden typ na druhý.

Keď sa pokúsime priradiť premennú z veľkého typu na menší, Java vygeneruje chybu, nekompatibilné typy: možná stratová konverzia, pri zostavovaní kódu.

Skúsme napríklad priradiť a dlho do an int:

long longNum = 10; int intNum = longNum;

Počas kompilácie tohto kódu Java vydá chybu:

nekompatibilné typy: možná stratová konverzia z dlhej na int

Tu Java nájde dlho a int nekompatibilné a majú za následok stratovú chybu konverzie. Pretože môže byť dlho hodnoty mimo int rozsah -2 147 483 648 až 2 147 483 647.

Podobne skúsme priradiť a plavák do a dlho:

float floatNum = 10.12f; long longNum = floatNum;
nekompatibilné typy: možná stratová konverzia z float na long

Ako plavák môže mať desatinné hodnoty, ktoré nezodpovedajú dlho hodnotu. Dostaneme preto rovnakú chybu.

Podobne priradenie a dvojitý číslo na int spôsobí rovnakú chybu:

double doubleNum = 1,2; int intNum = doubleNum;
nekompatibilné typy: možná stratová konverzia z dvojitého na int

The dvojitý hodnoty môžu byť pre súbor príliš veľké alebo príliš malé int a desatinné hodnoty sa pri prepočte stratia. Ide teda o potenciálne stratovú konverziu.

Túto chybu môžeme naraziť aj pri vykonávaní jednoduchého výpočtu:

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

Keď dvojitý množiť s int, dostaneme výsledok v a dvojitý. V dôsledku toho je to tiež potenciálna stratová konverzia.

Preto nekompatibilné typy v stratová konverzia môže mať rôzne veľkosti alebo typy (celé čísla alebo desatinné miesta).

3. Primitívne dátové typy

V Jave je k dispozícii veľa primitívnych dátových typov s ich zodpovedajúcimi triedami obalov.

Ďalej zostavíme praktický zoznam všetkých možných stratových konverzií v Jave:

  • krátky do bajt alebo char
  • char do bajt alebo krátky
  • int do bajt, krátky alebo char
  • dlho do bajt, krátky, char alebo int
  • plavák do bajt, krátky, char, int alebo dlho
  • dvojitý do bajt, krátky, char, int, dlho alebo plavák

Všimnite si to však krátky a char mať rovnakú veľkosť. Napriek tomu prevod z krátky do char je stratová, pretože char je nepodpísaný dátový typ.

4. Techniky premeny

4.1. Konverzia medzi primitívnymi typmi

Jednoduchý spôsob premeny primitívov, aby sa zabránilo stratovej konverzii, je downcasting; inými slovami, casting väčšieho typu na menší. Preto sa mu hovorí aj zúženie primitívnej konverzie.

Poďme napríklad konvertovať pozdĺž číslo na a krátky pomocou downcastingu:

long longNum = 24; short shortNum = (short) longNum; assertEquals (24, shortNum);

Podobne konvertujme a dvojitý do an int:

double doubleNum = 15,6; int integerNum = (int) doubleNum; assertEquals (15, integerNum);

Mali by sme si však uvedomiť, že konverzia veľkého typu s hodnotami príliš veľkými alebo príliš malými na menšie typy prostredníctvom downcastingu môže mať za následok neočakávané hodnoty.

Poďme konvertovať dlho hodnoty mimo rozsah krátky:

long largeLongNum = 32768; krátke minShortNum = (krátke) largeLongNum; assertEquals (-32768, minShortNum); long smallLongNum = -32769; krátke maxShortNum = (krátke) smallLongNum; assertEquals (32767, maxShortNum);

Ak konverziu starostlivo analyzujeme, zistíme, že nejde o očakávané hodnoty.

Inými slovami, keď Java pri konverzii z veľkého typu dosiahne najvyššiu hodnotu typu malej veľkosti, ďalšie číslo je najnižšia hodnota typu malej veľkosti a naopak.

Poďme to pochopiť na príkladoch. Kedy largeLongNum s hodnotou 32768 sa prevedie na krátky, hodnota shortNum1 je -32768. Pretože maximálna hodnota krátky je 32767, preto Java použije nasledujúcu minimálnu hodnotu súboru krátky.

Podobne, keď smallLongNum sa prevádza na krátky. Hodnota shortNum2 je 32767, pretože Java ide o ďalšiu maximálnu hodnotu súboru krátky.

Pozrime sa tiež, čo sa stane, keď prevedieme maximálnu a minimálnu hodnotu a dlho do an int:

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

4.2. Konverzia medzi obalovými objektmi a primitívnymi typmi

Aby sme priamo konvertovali obalový objekt na primitívny, môžeme v obálkových triedach použiť rôzne metódy ako napr intValue (), shortValue () a longValue (). Toto sa volá rozbaľovanie.

Napríklad preveďme a Plavák namietať voči a dlho:

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

Pokiaľ sa pozrieme aj na implementáciu longValue alebo podobné metódy, nájdeme použitie zúženia primitívnej konverzie:

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

Niekedy by sa však malo zabrániť zúženiu primitívnej konverzie, aby sa zachránili cenné informácie:

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

Po prepočte hodnota longNum bude 15. Avšak doubleNum je 15,9999, čo je veľmi blízko 16.

Namiesto toho môžeme použiť Math.round () pre prevod na najblizsie cele cislo:

Double doubleNum = 15,9999; long longNum = Math.round (doubleNum); assertEquals (16, longNum);

4.3. Konverzia medzi obalovými objektmi

Na to použijeme už diskutované techniky prevodu.

Najprv prevedieme obalový objekt na primitívnu hodnotu, zmenšiť ho a previesť na iný obalový objekt. Inými slovami, vykonáme techniky vybaľovania z boxu, downcastingu a boxu.

Poďme napríklad previesť a Dvojitý namietať proti Celé číslo objekt:

Double doubleNum = 10,3; double dbl = doubleNum.doubleValue (); // unboxing int intgr = (int) dbl; // downcasting Integer intNum = Integer.valueOf (intgr); assertEquals (Integer.valueOf (10), intNum); 

Nakoniec používame Celé číslo.hodnota() previesť primitívny typ int do an Celé číslo objekt. Tento typ premeny sa nazýva box.

5. Záver

V tomto článku sme pomocou niekoľkých príkladov preskúmali koncept stratovej konverzie v prostredí Java. Okrem toho sme zostavili praktický zoznam všetkých možných stratových konverzií.

Počas toho sme identifikovali zúženie primitívnej konverzie ako ľahkú techniku ​​na prevod primitívnych čísel a zabránenie stratovej chybe konverzie.

Zároveň sme preskúmali ďalšie užitočné techniky numerických prevodov v prostredí Java.

Implementácie kódu pre tento článok nájdete na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found