Tap av konvertering i Java

1. Oversikt

I denne raske opplæringen vil vi diskutere konseptet med tapskonvertering i Java og årsaken bak det.

Samtidig vil vi utforske noen nyttige konverteringsteknikker for å unngå denne feilen.

2. Tapende konvertering

Tap av konvertering er rett og slett tap av informasjon mens du håndterer data.

I Java tilsvarer det muligheten for å miste verdien eller presisjonen til en variabel under konvertering en type til en annen.

Når vi prøver å tilordne en variabel av stor størrelse til en mindre størrelse type, Java vil generere en feil, inkompatible typer: mulig tapskonvertering, mens du kompilerer koden.

La oss for eksempel prøve å tilordne en lang til en int:

lang langNum = 10; int intNum = longNum;

Java vil avgi en feil mens du kompilerer denne koden:

inkompatible typer: mulig lossy konvertering fra lang til int

Her vil Java finne lang og int inkompatibel og føre til tapsutsatte konverteringsfeil. For det kan være lang verdier utenfor int område -2,147,483,648 til 2,147,483,647.

På samme måte, la oss prøve å tilordne en flyte til en lang:

float floatNum = 10.12f; lang longNum = floatNum;
inkompatible typer: mulig tapskonvertering fra flyt til lang

Som flyte kan ha desimalverdier som ikke har tilsvarende lang verdi. Derfor får vi den samme feilen.

Tilsvarende tildeler en dobbelt nummer til et int vil forårsake den samme feilen:

dobbelt dobleNum = 1,2; int intNum = doubleNum;
inkompatible typer: mulig lossy konvertering fra dobbelt til int

De dobbelt verdiene kan være for store eller for små for en int og desimalverdier vil gå tapt i konverteringen. Derfor er det en potensiell tapsutsatt konvertering.

Vi kan også støte på denne feilen mens vi utfører en enkel beregning:

int fahrenheit = 100; int celcius = (fahrenheit - 32) * 5.0 / 9.0;

Når en dobbelt multipliser med en int, får vi resultatet i en dobbelt. Derfor er det også en potensiell tapskonvertering.

Derfor er de inkompatible typene i lossy konvertering kan enten ha forskjellige størrelser eller typer (heltall eller desimaler).

3. Primitive datatyper

I Java er det mange primitive datatyper tilgjengelig med tilhørende wrapper-klasser.

La oss deretter lage en praktisk liste over alle mulige tapskonverteringer i Java:

  • kort til byte eller røye
  • røye til byte eller kort
  • int til byte, kort eller røye
  • lang til byte, kort, røye eller int
  • flyte til byte, kort, røye, int eller lang
  • dobbelt til byte, kort, røye, int, lang eller flyte

Merk det skjønt kort og røye har samme størrelse. Fortsatt, konverteringen fra kort til røye er lossy fordi røye er en usignert datatype.

4. Konverteringsteknikker

4.1. Konvertering mellom primitive typer

Den enkle måten å konvertere primitiver for å unngå tapskonvertering er gjennom nedkastning; med andre ord, støping av større størrelse til en mindre størrelse. Derfor kalles det også innsnevring av primitiv konvertering.

La oss for eksempel konvertere langs nummer til a kort ved hjelp av downcasting:

lang langNum = 24; kort shortNum = (kort) longNum; assertEquals (24, shortNum);

På samme måte, la oss konvertere en dobbelt til en int:

dobbelt dobleNum = 15,6; int heltallNum = (int) dobbeltNum; assertEquals (15, integerNum);

Vi bør imidlertid være oppmerksom på at konvertering av stor størrelse med verdier som er for store eller for små til mindre størrelser gjennom nedkastning kan resultere i uventede verdier.

La oss konvertere lang verdier utenfor området for kort:

lang largeLongNum = 32768; kort minShortNum = (kort) largeLongNum; assertEquals (-32768, minShortNum); lang smallLongNum = -32769; kort maxShortNum = (kort) smallLongNum; assertEquals (32767, maxShortNum);

Hvis vi nøye analyserer konverteringen, ser vi at dette ikke er de forventede verdiene.

Med andre ord, når Java treffer den høyeste verdien av en liten størrelse mens du konverterer fra en stor størrelse, neste tall er den laveste verdien av liten størrelse og omvendt.

La oss forstå dette gjennom eksempler. Når largeLongNum med verdien 32768 konverteres til kort, verdien av shortNum1 er -32768. Fordi maksverdien på kort er 32767, derfor går Java for neste min verdi av kort.

Tilsvarende når smallLongNum konverteres til kort. Verdien av shortNum2 er 32767 ettersom Java går for den neste maksimale verdien av kort.

La oss også se hva som skjer når vi konverterer maks og min verdiene til a lang til en int:

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

4.2. Konvertering mellom innpakningsobjekter og primitive typer

For å direkte konvertere et innpakningsobjekt til et primitivt, kan vi bruke forskjellige metoder i innpakningsklasser som intValue (), shortValue () og longValue (). Dette kalles unboxing.

La oss for eksempel konvertere en Flyte motsette seg en lang:

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

Også, hvis vi ser på implementeringen av longValue eller lignende metoder, finner vi bruken av innsnevring av primitiv konvertering:

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

Imidlertid bør innsnevring av primitiv konvertering til tider unngås for å spare verdifull informasjon:

Dobbelt dobbelNum = 15.9999; lang longNum = doubleNum.longValue (); assertEquals (15, longNum); 

Etter konvertering, verdien av longNum blir 15. Imidlertid vil doubleNum er 15.9999, som er veldig nær 16.

I stedet kan vi bruke Math.round () for konvertering til nærmeste heltall:

Dobbelt dobbeltNum = 15.9999; lang longNum = Math.round (doubleNum); assertEquals (16, longNum);

4.3. Konvertere mellom innpakningsobjekter

For dette, la oss bruke de allerede diskuterte konverteringsteknikkene.

Først konverterer vi innpakningsobjekt til en primitiv verdi, nedkast det og konverter det til et annet innpakningsobjekt. Med andre ord vil vi utføre teknikker for unboxing, downcasting og boksing.

La oss for eksempel konvertere en Dobbelt motsette seg et Heltall gjenstand:

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

Til slutt bruker vi Heltall.verdien av() for å konvertere den primitive typen int til en Heltall gjenstand. Denne typen konvertering kalles boksing.

5. Konklusjon

I denne artikkelen har vi utforsket begrepet lossy konvertering i Java ved hjelp av en rekke eksempler. I tillegg har vi samlet en praktisk liste over alle mulige tapskonverteringer også.

Underveis har vi identifisert innsnevring av primitiv konvertering som en enkel teknikk for å konvertere primitive tall og unngå den tapende konverteringsfeilen.

Samtidig har vi også utforsket flere nyttige teknikker for numeriske konverteringer i Java.

Kodeimplementeringene for denne artikkelen finner du på GitHub.


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