1. Typecasting

Typecasting i Java

Variabler av primitive typer (med unntak av typen boolean) brukes til å lagre ulike typer tall. Selv om typene variabler aldri endret seg, er det et sted hvor du kan konvertere fra en type til en annen. Og det stedet er oppdrag .

Variabler av forskjellige typer kan tilordnes til hverandre. Når du gjør dette, blir verdien av en variabel av én type konvertert til en verdi av en annen type og tilordnet den andre variabelen. I denne forbindelse kan vi identifisere to typer typekonvertering: utvidelse og innsnevring.

Utvidelse er som å flytte en verdi fra en liten kurv til en stor: denne operasjonen er sømløs og smertefri. Innsnevring skjer når du flytter en verdi fra en stor kurv til en liten: det kan hende at det ikke er nok plass, og du må kaste noe.

Her er typene, sortert etter kurvstørrelse:

Typecasting i Java 2


2. Utvidelsestypekonverteringer

Det er ofte nødvendig å tilordne en variabel av én numerisk type til en variabel av en annen numerisk type. Hvordan gjør du det?

Java har 4 heltallstyper:

Type Størrelse
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Variable lagret i mindre kurver kan alltid tilordnes variabler lagret i større kurver.

int, shortog bytevariabler kan enkelt tilordnes til longvariabler. shortog bytevariabler kan tilordnes til intvariabler. Og bytevariabler kan tilordnes shortvariabler.

Eksempler:

Kode Beskrivelse
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Denne koden vil kompilere helt fint.

En slik konvertering, fra en mindre til en større type, kalles en utvidende typekonvertering.

Hva med reelle tall?

Med dem er alt det samme - størrelsen betyr noe:

Type Størrelse
float 4 bytes
double 8 bytes

floatvariabler kan tilordnes doublevariabler uten problemer. Men ting er mer interessant med heltallstypene.

Du kan tilordne en hvilken som helst heltallsvariabel til en floatvariabel. Til og med longtypen, som er 8 byte lang. Og du kan tilordne hva du vil - hvilken som helst heltallsvariabel eller floatvariabel - til en doublevariabel:

Kode Merk
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Vær oppmerksom på at konvertering til en reell type kan føre til tap av presisjon på grunn av mangel på tilstrekkelig signifikante sifre.

Når du konverterer fra heltall til flyttall, kan de lavere ordensdelene av tall forkastes. Men siden brøktall forstås å lagre omtrentlige verdier, er slike tilordningsoperasjoner tillatt.


3. Besnærende type konverteringer

Hva med de andre mulighetene? Hva om du trenger å tilordne en longverdi til en intvariabel?

Se for deg en variabel som en kurv. Vi har kurver i forskjellige størrelser: 1, 2, 4 og 8 byte. Det er ikke noe problem å overføre epler fra en mindre kurv til en større. Men når du skifter fra en større kurv til en mindre, kan noen av eplene gå tapt.

Denne transformasjonen - fra en større type til en mindre type - kalles en innsnevringstypekonvertering . Når du utfører en tilordningsoperasjon som denne, kan det hende at en del av et tall rett og slett ikke passer inn i den nye variabelen og kan derfor bli forkastet.

Når vi begrenser en type, må vi eksplisitt fortelle kompilatoren at vi ikke gjør en feil, at vi bevisst forkaster en del av nummeret. Typecast-operatoren brukes til dette. Det er et typenavn i parentes .

I slike situasjoner krever Java-kompilatoren at programmereren spesifiserer typecast-operatøren. Generelt ser det slik ut:

(type) expression

Eksempler:

Kode Beskrivelse
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Hver gang skal typecast-operatøren angis eksplisitt

Her aer lik 1, og kanskje typecast-operatøren virker som overkill. Men hva om ade var større?

Kode Beskrivelse
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

En million passer perfekt inn i en longog inn i en int. Men når man tilordner én million til en shortvariabel, forkastes de to første bytene, og bare de to siste bytene beholdes. Og når du tilordner til en byte, er det eneste som gjenstår den siste byten.

Hvordan tallene er ordnet i minnet:

Type Binær notasjon Desimalnotasjon
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

chartype

A char, som en short, opptar to byte, men for å konvertere en til en annen, må du alltid bruke en typecast-operator. Problemet her er at shorttypen er signert og kan inneholde verdier fra -32,768til +32,767, men chartypen er usignert og kan inneholde verdier fra 0til 65,535.

Negative tall kan ikke lagres i en char, men de kan lagres i en short. Og a shortkan ikke lagre tall større enn 32,767, men slike tall kan lagres i en char.


4. Type uttrykk

Hva om variabler av forskjellige typer brukes i samme uttrykk? Logisk sett forstår vi at de først må konverteres til en vanlig type. Men hvilken?

Til den større, selvfølgelig.

Java konverterer alltid til den større typen. Grovt sett utvides først en av typen og først deretter utføres operasjonen med verdier av samme type.

Hvis an intog a longer involvert i et uttrykk, vil verdien av intkonverteres til a longog først da vil operasjonen fortsette:

Kode Beskrivelse
int a = 1;
long b = 2;
long c = a + b;
autvides til a longog så vil tillegget skje.

Flytende tall

Hvis et heltall og et flyttall ( floateller double) er involvert i et uttrykk, vil heltall bli konvertert til et flyttall ( floateller double), og først da vil operasjonen bli utført.

Hvis operasjonen involverer a floatog a double, vil den floatbli konvertert til en double. Som faktisk er forventet.

Overraskelse

Typene byte, short, og charkonverteres alltid til intnår de samhandler med hverandre. Det er en god grunn til at typen intanses som standard heltallstype.

Hvis du ganger a bytemed a short, får du en int. Hvis du ganger a bytemed a byte, får du en int. Selv om du legger til en byteog en byte, får du en int.

Det er flere grunner til dette. Eksempler:

Kode Beskrivelse
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120er 13,200, som er litt større enn maksimumsverdien for bytetypen:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120er 230, som også er litt større enn maksimumsverdien for bytetypen:127

Generelt, når vi multipliserer et 8-bits (1 byte) tall med et 8-biters (1 byte) tall, får vi et tall som opptar 16-bits biter (2 byte)

Som et resultat blir alle operasjoner med heltallstyper som er mindre enn intalltid umiddelbart konvertert til ints. Og det betyr at hvis du vil lagre resultatet av beregningen i en variabel av en type som er mindre enn en int, så må du alltid spesifisere typecast-operatoren.

Eksempler:

Kode Beskrivelse
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
Uttrykket byte * bytevil være enint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
Uttrykket byte + bytevil være enint
byte a = 1;
byte b = (byte) (a + 1);
Uttrykket byte + intvil være en int
Den bokstavelige er en int.

5. En viktig nyanse

Typecast-operatøren har ganske høy prioritet.

Det betyr at hvis et uttrykk inneholder for eksempel addisjon og en typecast-operator, vil typecasten utføres før tillegget.

Eksempel:

Kode Beskrivelse
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
Typecast-operatoren vil bare bli brukt på avariabelen, som allerede er en byte. Denne koden vil ikke kompilere.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Dette er den riktige måten.

Hvis du vil konvertere hele uttrykket til en spesifikk type, og ikke bare én komponent av uttrykket, så pakk inn hele uttrykket i parentes og sett typecast-operatoren foran.