1. Typecasting
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:
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
, short
og byte
variabler kan enkelt tilordnes til long
variabler. short
og byte
variabler kan tilordnes til int
variabler. Og byte
variabler kan tilordnes short
variabler.
Eksempler:
Kode | Beskrivelse |
---|---|
|
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 |
float
variabler kan tilordnes double
variabler uten problemer. Men ting er mer interessant med heltallstypene.
Du kan tilordne en hvilken som helst heltallsvariabel til en float
variabel. Til og med long
typen, som er 8 byte lang. Og du kan tilordne hva du vil - hvilken som helst heltallsvariabel eller float
variabel - til en double
variabel:
Kode | Merk |
---|---|
|
|
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 long
verdi til en int
variabel?
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 |
---|---|
|
Hver gang skal typecast-operatøren angis eksplisitt |
Her a
er lik 1
, og kanskje typecast-operatøren virker som overkill. Men hva om a
de var større?
Kode | Beskrivelse |
---|---|
|
|
En million passer perfekt inn i en long
og inn i en int
. Men når man tilordner én million til en short
variabel, 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 |
char
type
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 short
typen er signert og kan inneholde verdier fra -32,768
til +32,767
, men char
typen er usignert og kan inneholde verdier fra 0
til 65,535
.
Negative tall kan ikke lagres i en char
, men de kan lagres i en short
. Og a short
kan 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 int
og a long
er involvert i et uttrykk, vil verdien av int
konverteres til a long
og først da vil operasjonen fortsette:
Kode | Beskrivelse |
---|---|
|
a utvides til a long og så vil tillegget skje. |
Flytende tall
Hvis et heltall og et flyttall ( float
eller double
) er involvert i et uttrykk, vil heltall bli konvertert til et flyttall ( float
eller double
), og først da vil operasjonen bli utført.
Hvis operasjonen involverer a float
og a double
, vil den float
bli konvertert til en double
. Som faktisk er forventet.
Typene byte
, short
, og char
konverteres alltid til int
når de samhandler med hverandre. Det er en god grunn til at typen int
anses som standard heltallstype.
Hvis du ganger a byte
med a short
, får du en int
. Hvis du ganger a byte
med a byte
, får du en int
. Selv om du legger til en byte
og en byte
, får du en int
.
Det er flere grunner til dette. Eksempler:
Kode | Beskrivelse |
---|---|
|
110 * 120 er 13,200 , som er litt større enn maksimumsverdien for byte typen:127 |
|
110 + 120 er 230 , som også er litt større enn maksimumsverdien for byte typen: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 int
alltid umiddelbart konvertert til int
s. 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 |
---|---|
|
Uttrykket byte * byte vil være enint |
|
Uttrykket byte + byte vil være enint |
|
Uttrykket byte + int vil 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 |
---|---|
|
Typecast-operatoren vil bare bli brukt på a variabelen, som allerede er en byte . Denne koden vil ikke kompilere. |
|
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.