Pretvorba gubitaka u Javi
1. Pregled
U ovom brzom vodiču razgovarat ćemo o konceptu pretvorbe s gubicima u Javi i o razlozima iza toga.
Istodobno ćemo istražiti neke praktične tehnike pretvorbe kako bismo izbjegli ovu pogrešku.
2. Pretvorba gubitaka
Pretvorba gubitaka jednostavno je gubitak informacija tijekom rukovanja podacima. U Javi to odgovara mogućnosti gubljenje vrijednosti ili preciznosti varijable tijekom pretvorbe jedan tip drugom. Kada pokušamo dodijeliti varijablu od veliki tip do manjeg tipa, Java će generirati pogrešku, nekompatibilne vrste: moguća konverzija s gubitkom, tijekom sastavljanja koda. Na primjer, pokušajmo dodijeliti dugo do an int: Java će tijekom sastavljanja ovog koda izdati pogrešku: Ovdje će Java pronaći dugo i int nespojivo i rezultira pogreškom pretvorbe s gubitkom. Jer može biti dugo vrijednosti izvan int raspon -2,147,483,648 do 2,147,483,647. Slično tome, pokušajmo dodijeliti plutati do a dugo: Kao plutati mogu imati decimalne vrijednosti koje nemaju odgovarajuće dugo vrijednost. Stoga ćemo primiti istu pogrešku. Slično tome, dodjeljivanje a dvostruko broj na an int će uzrokovati istu pogrešku: The dvostruko vrijednosti mogu biti prevelike ili premale za int a decimalne vrijednosti će se izgubiti u pretvorbi. Dakle, to je potencijalna konverzija s gubitkom. Također, možemo naići na ovu pogrešku tijekom izvođenja jednostavnog izračuna: Kad dvostruko pomnoži s int, rezultat dobivamo u a dvostruko. Posljedično, to je također potencijalna konverzija s gubitkom. Stoga nespojivi tipovi u pretvorba s gubicima može imati različite veličine ili vrste (cijeli brojevi ili decimale). U Javi postoje mnogi primitivni tipovi podataka s pripadajućim klasama omotača. Dalje, sastavimo zgodan popis svih mogućih pretvorbi s gubicima u Javi: Imajte na umu da ipak kratak i ugljen imaju istu veličinu. Još, pretvorba iz kratak do ugljen je gubitak jer ugljen je nepotpisana vrsta podataka. Jednostavan način pretvaranja primitiva kako bi se izbjegla pretvorba s gubitkom je spuštanje prema dolje; drugim riječima, lijevanje tipa veće veličine na tip manje veličine. Stoga se to naziva i sužavanjem primitivne konverzije. Na primjer, pretvorimo dugo broj do a kratak koristeći downcasting: Slično tome, pretvorimo a dvostruko do an int: Međutim, trebali bismo imati na umu da pretvaranje velikoga tipa s vrijednostima koje su prevelike ili premale u manje veličine putem downcastinga može rezultirati neočekivanim vrijednostima. Pretvorimo se dugo vrijednosti izvan raspona kratak: Ako pažljivo analiziramo pretvorbu, vidjet ćemo da to nisu očekivane vrijednosti. Drugim riječima, kada Java dosegne najveću vrijednost malog tipa dok pretvara iz velikog tipa, sljedeći je broj najniža vrijednost tipa male veličine i obrnuto. Shvatimo to kroz primjere. Kada largeLongNum s vrijednošću od 32768 pretvara se u kratak, vrijednost shortNum1 je -32768. Budući da je maksimalna vrijednost kratak je 32767, dakle, Java ide za sljedeću minimalnu vrijednost kratak. Slično tome, kada smallLongNum pretvara se u kratak. Vrijednost shortNum2 je 32767 dok Java ide za sljedeću maksimalnu vrijednost kratak. Također, pogledajmo što će se dogoditi kada pretvorimo maksimalnu i minimalnu vrijednost a dugo do an int: Da bismo izravno pretvorili objekt omotača u primitiv, možemo koristiti razne metode u klasama omotača poput intValue (), kratka vrijednost () i longValue (). Ovo se zove Raspakirati. Na primjer, pretvorimo a Plutati prigovoriti a dugo: Također, ako pogledamo provedbu longValue ili slične metode, naći ćemo upotrebu sužavanja primitivne pretvorbe: Međutim, ponekad treba izbjegavati sužavanje primitivne pretvorbe radi spremanja vrijednih podataka: Nakon pretvorbe, vrijednost longNum bit će 15. Međutim, doubleNum je 15,9999, što je vrlo blizu 16. Umjesto toga, možemo koristiti Matematika.okruženje () za pretvorbu u najbliži cijeli broj: Za to se poslužimo već raspravljenim tehnikama pretvorbe. Prvo ćemo pretvoriti omotački objekt na primitivnu vrijednost, spustite ga i pretvorite u drugi objekt omota. Drugim riječima, izvodit ćemo tehnike otpakiranja, spuštanja i boksa. Na primjer, pretvorimo a Dvostruko prigovoriti an Cijeli broj objekt: Na kraju, koristimo Cijeli broj.vrijednost() pretvoriti primitivni tip int do an Cijeli broj objekt. Ova vrsta pretvorbe se naziva boks. U ovom smo članku istražili koncept pretvorbe s gubicima u Javi uz pomoć nekoliko primjera. Osim toga, sastavili smo i zgodan popis svih mogućih konverzija s gubicima. Usput smo identificirali sužavanje primitivne pretvorbe kao jednostavnu tehniku pretvorbe primitivnih brojeva i izbjegavanja pogreške pretvorbe s gubitkom. Istodobno smo istražili i dodatne praktične tehnike za numeričke pretvorbe u Javi. Implementacije koda za ovaj članak mogu se naći na GitHubu.long longNum = 10; int intNum = longNum;
nespojive vrste: moguća konverzija s gubitkom iz dugog u unutarnji
float floatNum = 10,12f; long longNum = floatNum;
nekompatibilne vrste: moguća konverzija s gubitkom iz plutajućeg u dugi
dvostruki doubleNum = 1,2; int intNum = doubleNum;
nespojive vrste: moguća konverzija s gubicima iz dvostruke u int
int fahrenheit = 100; int celcius = (fahrenheit - 32) * 5,0 / 9,0;
3. Primitivni tipovi podataka
4. Tehnike pretvorbe
4.1. Pretvaranje između primitivnih tipova
long longNum = 24; kratki shortNum = (kratki) longNum; assertEquals (24, shortNum);
dvostruki doubleNum = 15,6; int integerNum = (int) doubleNum; assertEquals (15, integerNum);
long largeLongNum = 32768; kratki minShortNum = (kratki) largeLongNum; assertEquals (-32768, minShortNum); long smallLongNum = -32769; kratki maxShortNum = (kratki) 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. Pretvaranje između omotačkih predmeta i primitivnih tipova
Float floatNum = 17.564f; long longNum = floatNum.longValue (); assertEquals (17, longNum);
public long longValue () {return (duga) vrijednost; }
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. Pretvaranje između omotanih predmeta
Double doubleNum = 10,3; dvostruki dbl = doubleNum.doubleValue (); // raspakiranje int intgr = (int) dbl; // spuštanje cijelog broja IntNum = Integer.valueOf (intgr); assertEquals (Integer.valueOf (10), intNum);
5. Zaključak