1. Typecasting
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:
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
, short
og byte
variabler kan nemt tildeles til long
variabler. short
og byte
variabler kan tildeles int
variabler. Og byte
variabler kan tildeles short
variabler.
Eksempler:
Kode | Beskrivelse |
---|---|
|
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 |
float
variabler kan tildeles double
variabler uden problemer. Men tingene er mere interessante med heltalstyperne.
Du kan tildele enhver heltalsvariabel til en float
variabel. Selv long
typen, som er 8 bytes lang. Og du kan tildele, hvad du vil - enhver heltalsvariabel eller float
variabel - til en double
variabel:
Kode | Bemærk |
---|---|
|
|
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 long
værdi til en int
variabel?
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 |
---|---|
|
Hver gang skal typecast-operatøren angives eksplicit |
Her a
er lig med 1
, og måske virker typecast-operatøren som overkill. Men hvad hvis a
de var større?
Kode | Beskrivelse |
---|---|
|
|
En million passer perfekt ind i en long
og i en int
. Men når man tildeler en million til en short
variabel, 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 |
char
type
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 short
typen er signeret og kan indeholde værdier fra -32,768
til +32,767
, men char
typen er usigneret og kan indeholde værdier fra 0
til 65,535
.
Negative tal kan ikke gemmes i en char
, men de kan gemmes i en short
. Og a short
kan 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 int
og a long
er involveret i et udtryk, vil værdien af den int
blive konverteret til a long
og først derefter vil operationen fortsætte:
Kode | Beskrivelse |
---|---|
|
a vil blive udvidet til a long og så vil tilføjelsen ske. |
Flydende kommatal
Hvis et heltal og et flydende tal ( float
eller double
) er involveret i et udtryk, vil hele tallet blive konverteret til et flydende deal ( float
eller double
), og først derefter vil operationen blive udført.
Hvis operationen involverer a float
og a double
, vil den float
blive konverteret til en double
. Hvilket faktisk forventes.
Typerne byte
, short
, og char
konverteres altid til, int
når de interagerer med hinanden. Der er en god grund til, at typen int
betragtes som standard heltalstypen.
Hvis du gange a byte
med a short
, får du en int
. Hvis du gange a byte
med a byte
, får du en int
. Selvom du tilføjer a byte
og a byte
, får du en int
.
Det er der flere grunde til. Eksempler:
Kode | Beskrivelse |
---|---|
|
110 * 120 er 13,200 , hvilket er lidt større end den maksimale værdi af byte typen:127 |
|
110 + 120 er 230 , hvilket også er lidt større end den maksimale værdi af byte typen: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, int
altid straks til int
s. 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 |
---|---|
|
Udtrykket byte * byte vil være enint |
|
Udtrykket byte + byte vil være enint |
|
Udtrykket byte + int vil 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 |
---|---|
|
Typecast-operatoren vil kun blive anvendt på a variablen, som allerede er en byte . Denne kode vil ikke kompilere. |
|
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.
GO TO FULL VERSION