1. Typecasting

Typecasting i Java

Variabler av primitiva typer (med undantag för booleantypen) används för att lagra olika typer av tal. Även om typerna av variabler aldrig ändrades, finns det en plats där du kan konvertera från en typ till en annan. Och den platsen är uppdrag .

Variabler av olika typer kan tilldelas varandra. När du gör detta konverteras värdet av en variabel av en typ till ett värde av en annan typ och tilldelas den andra variabeln. I detta avseende kan vi identifiera två typer av typkonvertering: breddning och avsmalning.

Att bredda är som att flytta ett värde från en liten korg till en stor: denna operation är sömlös och smärtfri. Avsmalning händer när du flyttar ett värde från en stor korg till en liten: det kanske inte finns tillräckligt med utrymme och du måste slänga något.

Här är typerna, sorterade efter korgstorlek:

Typecasting i Java 2


2. Breddande typkonverteringar

Det är ofta nödvändigt att tilldela en variabel av en numerisk typ till en variabel av en annan numerisk typ. Hur gör man det?

Java har 4 heltalstyper:

Typ Storlek
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Variabel lagrad i mindre korgar kan alltid tilldelas variabler lagrade i större korgar.

int, shortoch bytevariabler kan enkelt tilldelas till longvariabler. shortoch bytevariabler kan tilldelas intvariabler. Och bytevariabler kan tilldelas shortvariabler.

Exempel:

Koda Beskrivning
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Den här koden kommer att kompileras bra.

En sådan omvandling, från en mindre till en större typ, kallas en omvandling av breddningstyp .

Hur är det med reella siffror?

Med dem är allt sig likt - storleken spelar roll:

Typ Storlek
float 4 bytes
double 8 bytes

floatvariabler kan tilldelas doublevariabler utan problem. Men saker och ting är mer intressanta med heltalstyperna.

Du kan tilldela vilken heltalsvariabel som helst till en floatvariabel. Även longtypen, som är 8 byte lång. Och du kan tilldela vad du vill - vilken heltalsvariabel eller floatvariabel som helst - till en doublevariabel:

Koda Notera
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Observera att konvertering till en riktig typ kan resultera i förlust av precision på grund av bristen på tillräckligt med signifikanta siffror.

När du konverterar från heltal till flyttal, kan de lägre ordningens delar av tal kasseras. Men eftersom bråktal förstås lagra ungefärliga värden, är sådana tilldelningsoperationer tillåtna.


3. Begränsande typkonverteringar

Hur är det med de andra möjligheterna? Vad händer om du behöver tilldela ett longvärde till en intvariabel?

Föreställ dig en variabel som en korg. Vi har korgar i olika storlekar: 1, 2, 4 och 8 byte. Det är inga problem att flytta äpplen från en mindre korg till en större. Men när man byter från en större korg till en mindre kan en del av äpplena gå förlorade.

Denna omvandling – från en större typ till en mindre typ – kallas en avsmalnande typkonvertering . När du utför en tilldelningsoperation som denna kanske en del av ett nummer helt enkelt inte passar in i den nya variabeln och kan därför kasseras.

När vi begränsar en typ måste vi uttryckligen tala om för kompilatorn att vi inte gör ett misstag, att vi medvetet kasserar en del av numret. Typecast-operatorn används för detta. Det är ett typnamn inom parentes .

I sådana situationer kräver Java-kompilatorn att programmeraren anger typecast-operatören. I allmänhet ser det ut så här:

(type) expression

Exempel:

Koda Beskrivning
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Varje gång måste typcast-operatören anges uttryckligen

Här aär lika med 1, och kanske verkar typecast-operatören som överdriven. Men tänk om de avar större?

Koda Beskrivning
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

En miljon passar perfekt in i en longoch en int. Men när man tilldelar en miljon till en shortvariabel, kasseras de två första byten, och endast de två sista byten behålls. Och när du tilldelar en byte, är det enda som återstår den sista byten.

Hur siffrorna är ordnade i minnet:

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

chartyp

A char, som en short, upptar två byte, men för att konvertera en till en annan behöver du alltid använda en typecast-operator. Problemet här är att shorttypen är signerad och kan innehålla värden från -32,768till +32,767, men chartypen är osignerad och kan innehålla värden från 0till 65,535.

Negativa tal kan inte lagras i en char, men de kan lagras i en short. Och a shortkan inte lagra nummer större än 32,767, men sådana nummer kan lagras i en char.


4. Typ av uttryck

Vad händer om variabler av olika typer används i samma uttryck? Logiskt sett förstår vi att de först måste konverteras till en vanlig typ. Men vilken?

Till den större förstås.

Java konverterar alltid till den större typen. Grovt sett breddas först en av typen och först därefter utförs operationen med värden av samma typ.

Om an intoch a longär inblandade i ett uttryck, kommer värdet av den intatt konverteras till a longoch först då fortsätter operationen:

Koda Beskrivning
int a = 1;
long b = 2;
long c = a + b;
akommer att breddas till a longoch då kommer tillägget att ske.

Flyttal

Om ett heltal och ett flyttal ( floateller double) är inblandade i ett uttryck, kommer heltal konverteras till ett flyttal ( floateller double), och först då kommer operationen att utföras.

Om operationen involverar a floatoch a konverteras doubleden till en . Vilket faktiskt förväntas.floatdouble

Överraskning

Typerna byte, short, och charkonverteras alltid till intnär de interagerar med varandra. Det finns en bra anledning till varför inttypen anses vara standard heltalstyp.

Om du multiplicerar a bytemed a shortfår du en int. Om du multiplicerar a bytemed a bytefår du en int. Även om du lägger till a byteoch a bytefår du en int.

Det finns flera anledningar till detta. Exempel:

Koda Beskrivning
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120är 13,200, vilket är något större än maxvärdet för bytetypen:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120är 230, vilket också är något större än maxvärdet för bytetypen:127

I allmänhet, när vi multiplicerar ett 8-bitars (1 byte) tal med ett 8-bitars (1 byte) tal, får vi ett tal som upptar 16-bitars bitar (2 byte)

Som ett resultat konverteras alla operationer med heltalstyper som är mindre än intalltid omedelbart till ints. Och det betyder att om du vill lagra resultatet av beräkningen i en variabel av en typ som är mindre än en , intmåste du alltid explicit specificera typecast-operatorn.

Exempel:

Koda Beskrivning
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
Uttrycket byte * byteblir enint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
Uttrycket byte + byteblir enint
byte a = 1;
byte b = (byte) (a + 1);
Uttrycket byte + intkommer att vara en int
Den bokstavliga är en int.

5. En viktig nyans

Typcast-operatören har ganska hög prioritet.

Det betyder att om ett uttryck innehåller till exempel addition och en typecast-operator, kommer typcasten att utföras före tillägget.

Exempel:

Koda Beskrivning
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
Typecast-operatorn kommer endast att tillämpas på avariabeln, som redan är en byte. Den här koden kommer inte att kompileras.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Detta är det korrekta sättet.

Om du vill konvertera hela uttrycket till en specifik typ, och inte bara en komponent i uttrycket, linda in hela uttrycket inom parentes och sätt typcastoperatorn framför.