CodeGym /Java-blogg /Tilfeldig /Utvidelse og innsnevring av primitive typer
John Squirrels
Nivå
San Francisco

Utvidelse og innsnevring av primitive typer

Publisert i gruppen
Hei! Etter hvert som du har kommet deg gjennom CodeGym, har du møtt primitive typer mange ganger. Her er en kort liste over hva vi vet om dem:
  1. De er ikke objekter og representerer en verdi som er lagret i minnet
  2. Det finnes flere typer
    • Hele tall: byte , short , int , long
    • Flytende tall (brøk): flytende og doble
    • Logiske verdier: boolske
    • Symbolske verdier (for å representere bokstaver og tall): char
  3. Hver type har sitt eget verdiområde:

Primitiv type Størrelse i minnet Verdiområde
byte 8 biter -128 til 127
kort 16 biter -32768 til 32767
røye 16 biter 0 til 65536
int 32 biter -2147483648 til 2147483647
lang 64 biter -9223372036854775808 til 9223372036854775807
flyte 32 biter (2 i potens av -149) til ((2 - (2 i potens av -23)) * 2 i potens av 127)
dobbelt 64 biter (-2 i potens av 63) til ((2 i potens av 63) - 1)
boolsk 8 (når brukt i matriser), 32 (hvis ikke brukt i matriser) sant eller usant
Men i tillegg til å ha ulike verdier, er de også forskjellige i hvor mye plass de opptar i minnet. En int tar mer enn en byte. Og en lang er større enn en kort. Mengden minne okkupert av primitiver kan sammenlignes med russiske hekkende dukker: Utvidelse og innsnevring av primitive typer - 2 Hver hekkende dukke har ledig plass inni. Jo større hekkende dukke, jo mer plass er det. En stor hekkende dukke ( lang ) vil lett romme en mindre inntrengning . Den passer lett og du trenger ikke gjøre noe annet. I Java, når du arbeider med primitiver, kalles dette implisitt konvertering. Eller sagt annerledes, det kalles utvidelse.

Utvidelse i Java

Her er et enkelt eksempel på en utvidende konvertering:

public class Main {

   public static void main(String[] args) {
      
       int bigNumber = 10000000;

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
Her tildeler vi en byte-verdi til en int- variabel. Oppdraget lykkes uten problemer: verdien som er lagret i en byte tar opp mindre minne enn hva en int kan romme. Den lille hekkende dukken (byteverdi) passer lett inn i den store hekkende dukken ( int variabel). Det er en annen sak om du prøver å gjøre det motsatte, dvs. å sette en stor verdi inn i en variabel hvis rekkevidde ikke kan romme en så stor datatype. Med ekte hekkende dukker ville tallet rett og slett ikke passet. Med Java kan det, men med nyanser. La oss prøve å sette en int i en kort variabel:

public static void main(String[] args) {

   int bigNumber = 10000000;
  
   short littleNumber = 1000;

   littleNumber = bigNumber;// Error!
   System.out.println(bigNumber);
}
Feil! Kompilatoren forstår at du prøver å gjøre noe unormalt ved å dytte en stor hekkende dukke ( int ) inni en liten ( kort ). I dette tilfellet er kompileringsfeilen en advarsel fra kompilatoren: "Hei, er du helt sikker på at du vil gjøre dette?" Hvis du er sikker, sier du til kompilatoren: "Alt er i orden. Jeg vet hva jeg gjør!" Denne prosessen kalles eksplisitt typekonvertering, eller innsnevring.

Innsnevring i Java

For å utføre en begrensende konvertering, må du eksplisitt angi typen du vil konvertere verdien til. Med andre ord, du må svare på kompilatorens spørsmål: "Vel, hvilken av disse små hekkende dukkene vil du sette denne store hekkende dukken i?" I vårt tilfelle ser det slik ut:

public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
Vi indikerer eksplisitt at vi ønsker å sette en int i en kort variabel og at vi tar ansvaret. Når kompilatoren ser at en smalere type er eksplisitt angitt, utfører kompilatoren konverteringen. Hva er resultatet? Konsollutgang: -27008 Det var litt uventet. Hvorfor fikk vi akkurat det? Faktisk er det hele veldig enkelt. Opprinnelig var verdien 10000000. Den ble lagret i en int- variabel, som opptar 32 biter. Dette er dens binære representasjon:
Utvidelse og innsnevring av primitive typer - 3
Vi skriver denne verdien inn i en kort variabel, som bare kan lagre 16 biter! Følgelig vil bare de første 16 bitene av nummeret vårt bli flyttet dit. Resten vil bli kastet. Som et resultat mottar den korte variabelen følgende verdi
Utvidelse og innsnevring av primitive typer - 4
som i desimalform er lik -27008 Det er derfor kompilatoren ber deg om å "bekrefte" ved å indikere en eksplisitt innsnevringskonvertering til en bestemt type. For det første viser dette at du tar ansvar for resultatet. Og for det andre forteller den kompilatoren hvor mye plass som skal tildeles når konvertering skjer. Tross alt, i det siste eksemplet, hvis vi tilordnet en int-verdi til en byte-variabel i stedet for en short , ville vi bare ha 8 bits til rådighet, ikke 16, og resultatet ville bli annerledes. Brøktyper ( float og dobbel ) har sin egen prosess for å begrense konverteringer. Hvis du prøver å kaste et fraksjonstall til en heltallstype, vil brøkdelen bli forkastet.

public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
Konsollutgang: 2

røye

Du vet allerede at tegn brukes til å vise individuelle tegn.

public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';
  
}
Men denne datatypen har flere funksjoner som er viktige å forstå. La oss se igjen på tabellen over verdiområder:
Primitiv type Størrelse i minnet Verdiområde
byte 8 biter -128 til 127
kort 16 biter -32768 til 32767
røye 16 biter 0 til 65536
int 32 biter -2147483648 til 2147483647
lang 64 biter -9223372036854775808 til 9223372036854775807
flyte 32 biter (2 i potens av -149) til ((2 - (2 i potens av -23)) * 2 i potens av 127)
dobbelt 64 biter (-2 i potens av 63) til ((2 i potens av 63) - 1)
boolsk 8 (når brukt i matriser), 32 (hvis ikke brukt i matriser) sant eller usant
Området 0 til 65536 er angitt for røyetypen . Men hva betyr det? Tross alt representerer en char ikke bare tall, men også bokstaver, skilletegn... Saken er at i Java er char- verdier lagret i Unicode-format. Vi har allerede møtt Unicode i en av de forrige leksjonene. Du husker sikkert at Unicode er en standard for tegnkoding som inkluderer symbolene til nesten alle verdens skriftspråk. Med andre ord, det er en liste over spesialkoder som representerer nesten alle tegn på ethvert språk. Hele Unicode-bordet er veldig stort, og det er selvfølgelig ikke nødvendig å lære det utenat. Her er en liten del av den: Utvidelse og innsnevring av primitive typer - 5 Det viktigste er å forstå hvordan tegn lagres, og å huske at hvis du kjenner koden for et bestemt tegn, kan du alltid produsere det tegnet i programmet ditt. La oss prøve med et tilfeldig tall:

public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
Konsollutgang: 耰 Dette er formatet som brukes til å lagre tegn i Java. Hvert symbol tilsvarer et tall: en 16-biters (to-byte) numerisk kode. I Unicode tilsvarer 32816 det kinesiske tegnet 耰. Legg merke til følgende punkt. I dette eksemplet brukte vi en int -variabel. Den opptar 32 biter i minnet, mens en char opptar 16. Her valgte vi en int , fordi nummeret vårt (32816) ikke får plass i en kort . Selv om størrelsen på en char (akkurat som en short ) er 16 biter, er det ingen negative tall i char- området, så den "positive" delen av charrekkevidden er dobbelt så stor (65536 i stedet for 32767 for den korte typen). Vi kan bruke en int så lenge koden vår holder seg under 65536. Men hvis du oppretter en int- verdi større enn 65536, vil den oppta mer enn 16 biter. Og dette vil resultere i en begrensende konvertering

char c = (char) x;
de ekstra bitene vil bli forkastet (som diskutert ovenfor) og resultatet vil være ganske uventet.

Spesielle funksjoner for å legge til tegn og heltall

La oss se på et uvanlig eksempel:

public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i + c);
   }
}
Konsollutgang: 50 O_О Hvordan gir det mening? 1+1. Hvor kom de 50 fra?! Du vet allerede at charverdier er lagret i minnet som tall i området fra 0 til 65536, og at disse tallene er en Unicode-representasjon av et tegn. Utvidelse og innsnevring av primitive typer - 6 Når vi legger til en char og en heltallstype, konverteres char til det tilsvarende Unicode-nummeret. I koden vår, da vi la til 1 og '1', ble symbolet '1' konvertert til sin egen kode, som er 49 (du kan bekrefte dette i tabellen ovenfor). Derfor er resultatet 50. La oss igjen ta vår gamle venn 耰 som eksempel, og prøve å legge det til et eller annet tall.

public static void main(String[] args) {

   char c = '耰';
   int x = 200;

   System.out.println(c + x);
}
Konsollutgang: 33016 Vi har allerede oppdaget at 耰 tilsvarer 32816. Og når vi legger til dette tallet og 200, får vi resultatet vårt: 33016. :) Som du kan se er algoritmen her ganske enkel, men du bør ikke glemme den .
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION