1. Typecasting

Typecasting i Java

Variabler af primitive typer (med undtagelse af typen boolean) bruges til at gemme forskellige typer tal. Selvom typerne af variabler aldrig ændrede sig, er der et sted, hvor du kan konvertere fra en type til en anden. Og det sted er opgave .

Variabler af forskellige typer kan tildeles hinanden. Når du gør dette, konverteres værdien af ​​en variabel af én type til en værdi af en anden type og tildeles den anden variabel. I denne forbindelse kan vi identificere to slags typekonvertering: udvidelse og indsnævring.

Udvidelse er som at flytte en værdi fra en lille kurv til en stor: denne operation er problemfri og smertefri. Indsnævring sker, når du flytter en værdi fra en stor kurv til en lille: Der er muligvis ikke plads nok, og du bliver nødt til at smide noget væk.

Her er typerne, sorteret efter kurvstørrelse:

Typecasting i Java 2


2. Udvidelse af typekonverteringer

Det er ofte nødvendigt at tildele en variabel af én numerisk type til en variabel af en anden numerisk type. Hvordan gør du det?

Java har 4 heltalstyper:

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

Variable lagret i mindre kurve kan altid tildeles variabler lagret i større kurve.

int, shortog bytevariabler kan nemt tildeles til longvariabler. shortog bytevariabler kan tildeles intvariabler. Og bytevariabler kan tildeles shortvariabler.

Eksempler:

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

En sådan konvertering, fra en mindre til en større type, kaldes en udvidelsestypekonvertering .

Hvad med reelle tal?

Med dem er alt det samme - størrelsen betyder noget:

Type Størrelse
float 4 bytes
double 8 bytes

floatvariabler kan tildeles doublevariabler uden problemer. Men tingene er mere interessante med heltalstyperne.

Du kan tildele enhver heltalsvariabel til en floatvariabel. Selv longtypen, som er 8 bytes lang. Og du kan tildele, hvad du vil - enhver heltalsvariabel eller floatvariabel - til en doublevariabel:

Kode Bemærk
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Bemærk, at konvertering til en rigtig type kan resultere i tab af præcision på grund af manglen på tilstrækkelige signifikante cifre.

Når du konverterer fra heltal til flydende kommatal, kan de lavere ordensdele af tal blive kasseret. Men da brøktal forstås at gemme omtrentlige værdier, er sådanne tildelingsoperationer tilladt.


3. Indsnævre type konverteringer

Hvad med de andre muligheder? Hvad hvis du skal tildele en longværdi til en intvariabel?

Forestil dig en variabel som en kurv. Vi har kurve i forskellige størrelser: 1, 2, 4 og 8 bytes. Det er ikke et problem at flytte æbler fra en mindre kurv til en større. Men når man skifter fra en større kurv til en mindre, kan nogle af æblerne gå tabt.

Denne transformation - fra en større type til en mindre type - kaldes en indsnævrende typekonvertering . Når du udfører en tildelingsoperation som denne, kan en del af et nummer simpelthen ikke passe ind i den nye variabel og kan derfor kasseres.

Når vi indsnævrer en type, skal vi udtrykkeligt fortælle compileren, at vi ikke laver en fejl, at vi bevidst kasserer en del af nummeret. Typecast-operatoren bruges til dette. Det er et typenavn i parentes .

I sådanne situationer kræver Java-kompileren , at programmøren angiver typecast-operatøren. Generelt ser det sådan ud:

(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 angives eksplicit

Her aer lig med 1, og måske virker typecast-operatøren som overkill. Men hvad hvis 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 ind i en longog i en int. Men når man tildeler en million til en shortvariabel, kasseres de første to bytes, og kun de sidste to bytes bibeholdes. Og når du tildeler til en byte, er det eneste, der er tilbage, den sidste byte.

Sådan er tallene arrangeret i hukommelsen:

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

chartype

A char, ligesom en short, optager to bytes, men for at konvertere den ene til en anden, skal du altid bruge en typecast-operator. Problemet her er, at shorttypen er signeret og kan indeholde værdier fra -32,768til +32,767, men chartypen er usigneret og kan indeholde værdier fra 0til 65,535.

Negative tal kan ikke gemmes i en char, men de kan gemmes i en short. Og a shortkan ikke gemme numre større end 32,767, men sådanne numre kan gemmes i en char.


4. Type af et udtryk

Hvad hvis variabler af forskellige typer bruges i det samme udtryk? Logisk set forstår vi, at de først skal konverteres til en almindelig type. Men hvilken?

Til den større, selvfølgelig.

Java konverterer altid til den større type. Groft sagt bliver en af ​​typen først udvidet og først derefter udføres operationen med værdier af samme type.

Hvis an intog a longer involveret i et udtryk, vil værdien af ​​den intblive konverteret til a longog først derefter vil operationen fortsætte:

Kode Beskrivelse
int a = 1;
long b = 2;
long c = a + b;
avil blive udvidet til a longog så vil tilføjelsen ske.

Flydende kommatal

Hvis et heltal og et flydende tal ( floateller double) er involveret i et udtryk, vil hele tallet blive konverteret til et flydende deal ( floateller double), og først derefter vil operationen blive udført.

Hvis operationen involverer a floatog a double, vil den floatblive konverteret til en double. Hvilket faktisk forventes.

Overraskelse

Typerne byte, short, og charkonverteres altid til, intnår de interagerer med hinanden. Der er en god grund til, at typen intbetragtes som standard heltalstypen.

Hvis du gange a bytemed a short, får du en int. Hvis du gange a bytemed a byte, får du en int. Selvom du tilføjer a byteog a byte, får du en int.

Det er der flere grunde til. Eksempler:

Kode Beskrivelse
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120er 13,200, hvilket er lidt større end den maksimale værdi af bytetypen:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120er 230, hvilket også er lidt større end den maksimale værdi af bytetypen:127

Generelt, når vi multiplicerer et 8-bit (1 byte) tal med et 8-bit (1 byte) tal, får vi et tal, der optager 16-bit bits (2 byte)

Som følge heraf konverteres alle operationer med heltalstyper, der er mindre end, intaltid straks til ints. Og det betyder, at hvis du vil gemme resultatet af beregningen i en variabel af en type, der er mindre end en int, så skal du altid eksplicit angive typecast-operatoren.

Eksempler:

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

5. En vigtig nuance

Typecast-operatøren har ret høj prioritet.

Det betyder, at hvis et udtryk f.eks. indeholder tilføjelse og en typecast-operator, udføres typecastet før tilføjelsen.

Eksempel:

Kode Beskrivelse
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
Typecast-operatoren vil kun blive anvendt på avariablen, som allerede er en byte. Denne kode vil ikke kompilere.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Dette er den rigtige måde.

Hvis du vil konvertere hele udtrykket til en bestemt type, og ikke kun én komponent af udtrykket, skal du pakke hele udtrykket i parentes og sætte typecast-operatoren foran.