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: Počas kompilácie tohto kódu Java vydá chybu: 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: 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: 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: 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). 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: 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. 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: Podobne konvertujme a dvojitý do an int: 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: 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: 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: Pokiaľ sa pozrieme aj na implementáciu longValue alebo podobné metódy, nájdeme použitie zúženia primitívnej konverzie: Niekedy by sa však malo zabrániť zúženiu primitívnej konverzie, aby sa zachránili cenné informácie: 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: 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: Nakoniec používame Celé číslo.hodnota() previesť primitívny typ int do an Celé číslo objekt. Tento typ premeny sa nazýva box. 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.long longNum = 10; int intNum = longNum;
nekompatibilné typy: možná stratová konverzia z dlhej na int
float floatNum = 10.12f; long longNum = floatNum;
nekompatibilné typy: možná stratová konverzia z float na long
double doubleNum = 1,2; int intNum = doubleNum;
nekompatibilné typy: možná stratová konverzia z dvojitého na int
int fahrenheit = 100; int celcius = (fahrenheit - 32) * 5,0 / 9,0;
3. Primitívne dátové typy
4. Techniky premeny
4.1. Konverzia medzi primitívnymi typmi
long longNum = 24; short shortNum = (short) longNum; assertEquals (24, shortNum);
double doubleNum = 15,6; int integerNum = (int) doubleNum; assertEquals (15, integerNum);
long largeLongNum = 32768; krátke minShortNum = (krátke) largeLongNum; assertEquals (-32768, minShortNum); long smallLongNum = -32769; krátke maxShortNum = (krátke) smallLongNum; assertEquals (32767, maxShortNum);
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
Float floatNum = 17,564f; long longNum = floatNum.longValue (); assertEquals (17, longNum);
public long longValue () {return (long) value; }
Double doubleNum = 15,9999; long longNum = doubleNum.longValue (); assertEquals (15, longNum);
Double doubleNum = 15,9999; long longNum = Math.round (doubleNum); assertEquals (16, longNum);
4.3. Konverzia medzi obalovými objektmi
Double doubleNum = 10,3; double dbl = doubleNum.doubleValue (); // unboxing int intgr = (int) dbl; // downcasting Integer intNum = Integer.valueOf (intgr); assertEquals (Integer.valueOf (10), intNum);
5. Záver