CodeGym /Java blog /Tilfældig /Udvidelse og indsnævring af primitive typer
John Squirrels
Niveau
San Francisco

Udvidelse og indsnævring af primitive typer

Udgivet i gruppen
Hej! Efterhånden som du er kommet videre gennem CodeGym, har du stødt på primitive typer mange gange. Her er en kort liste over, hvad vi ved om dem:
  1. De er ikke objekter og repræsenterer en værdi, der er gemt i hukommelsen
  2. Der er flere slags
    • Hele tal: byte , kort , int , lang
    • Flydende tal (brøktal): flydende og dobbelt
    • Logiske værdier: boolesk
    • Symbolske værdier (til at repræsentere bogstaver og tal): char
  3. Hver type har sit eget værdiområde:

Primitiv type Størrelse i hukommelsen Værdiinterval
byte 8 bits -128 til 127
kort 16 bits -32768 til 32767
char 16 bits 0 til 65536
int 32 bit -2147483648 til 2147483647
lang 64 bit -9223372036854775808 til 9223372036854775807
flyde 32 bit (2 i potens af -149) til ((2 - (2 i potens af -23)) * 2 i potens af 127)
dobbelt 64 bit (-2 i potens af 63) til ((2 i potens af 63) - 1)
boolesk 8 (når brugt i arrays), 32 (hvis ikke brugt i arrays) sandt eller falsk
Men udover at have forskellige værdier, er de også forskellige i, hvor meget plads de optager i hukommelsen. En int tager mere end en byte. Og en lang er større end en kort. Mængden af ​​hukommelse optaget af primitiver kan sammenlignes med russiske rededukker: Udvidelse og indsnævring af primitive typer - 2 Hver rededukke har ledig plads indeni. Jo større rededukken er, jo mere plads er der. En stor rededukke ( lang ) vil nemt kunne rumme en mindre int . Det passer nemt, og du behøver ikke at gøre andet. I Java, når man arbejder med primitiver, kaldes dette implicit konvertering. Eller sagt anderledes, det kaldes udvidelse.

Udvidelse i Java

Her er et simpelt eksempel på en udvidende 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 byteværdi til en int- variabel. Tildelingen lykkes uden problemer: værdien gemt i en byte fylder mindre hukommelse end hvad en int kan rumme. Den lille rededukke (byteværdi) passer nemt ind i den store rededukke ( int variabel). Det er en anden sag, hvis man forsøger at gøre det modsatte, altså at lægge en stor værdi ind i en variabel, hvis rækkevidde ikke kan rumme så stor en datatype. Med rigtige rededukker ville nummeret simpelthen ikke passe. Med Java kan det, men med nuancer. Lad os prøve at sætte 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);
}
Fejl! Compileren forstår, at du forsøger at gøre noget unormalt ved at skubbe en stor rededukke ( int ) ind i en lille ( kort ). I dette tilfælde er kompileringsfejlen en advarsel fra compileren: "Hej, er du helt sikker på , at du vil gøre dette?" Hvis du er sikker, så siger du til compileren: "Alt er okay. Jeg ved, hvad jeg laver!" Denne proces kaldes eksplicit typekonvertering eller indsnævring.

Indsnævring i Java

For at udføre en indsnævre konvertering skal du udtrykkeligt angive den type, du vil konvertere din værdi til. Du skal med andre ord svare på kompilatorens spørgsmål: "Nå, hvilken af ​​disse små rededukker vil du putte denne store rededukke i?" I vores tilfælde ser det sådan ud:

public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
Vi angiver udtrykkeligt, at vi ønsker at sætte en int i en kort variabel, og at vi tager ansvaret. Når du ser, at en smallere type er blevet eksplicit angivet, udfører compileren konverteringen. Hvad er resultatet? Konsol output: -27008 Det var lidt uventet. Hvorfor fik vi det præcist? Faktisk er det hele meget enkelt. Oprindeligt var værdien 10000000. Den blev gemt i en int- variabel, som optager 32 bit. Dette er dens binære repræsentation:
Udvidelse og indsnævring af primitive typer - 3
Vi skriver denne værdi ind i en kort variabel, som kun kan lagre 16 bit! Derfor vil kun de første 16 bits af vores nummer blive flyttet dertil. Resten vil blive kasseret. Som et resultat modtager den korte variabel følgende værdi
Udvidelse og indsnævring af primitive typer - 4
som i decimalform er lig med -27008 Det er derfor, compileren beder dig om at "bekræfte" ved at angive en eksplicit indsnævringskonvertering til en bestemt type. For det første viser dette, at du tager ansvar for resultatet. Og for det andet fortæller den compileren, hvor meget plads der skal tildeles, når konverteringen sker. Når alt kommer til alt, i det sidste eksempel, hvis vi tildelte en int-værdi til en byte-variabel i stedet for en short , ville vi kun have 8 bits til vores rådighed, ikke 16, og resultatet ville være anderledes. Fraktionelle typer ( float og double ) har deres egen proces til at indsnævre konverteringer. Hvis du prøver at caste et fraktionstal til en heltalstype, vil brøkdelen blive kasseret.

public static void main(String[] args) {

   double d = 2.7;

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

char

Du ved allerede, at tegn bruges til at vise individuelle tegn.

public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';
  
}
Men denne datatype har flere funktioner, som er vigtige at forstå. Lad os se igen på tabellen over værdiintervaller:
Primitiv type Størrelse i hukommelsen Værdiinterval
byte 8 bits -128 til 127
kort 16 bits -32768 til 32767
char 16 bits 0 til 65536
int 32 bit -2147483648 til 2147483647
lang 64 bit -9223372036854775808 til 9223372036854775807
flyde 32 bit (2 i potens af -149) til ((2 - (2 i potens af -23)) * 2 i potens af 127)
dobbelt 64 bit (-2 i potens af 63) til ((2 i potens af 63) - 1)
boolesk 8 (når brugt i arrays), 32 (hvis ikke brugt i arrays) sandt eller falsk
Området 0 til 65536 er angivet for char- typen. Men hvad betyder det? Når alt kommer til alt, repræsenterer et tegn ikke kun tal, men også bogstaver, tegnsætningstegn... Sagen er, at i Java er tegnværdier gemt i Unicode-format. Vi stødte allerede på Unicode i en af ​​de tidligere lektioner. Du husker sikkert, at Unicode er en tegnkodningsstandard, der indeholder symbolerne på næsten alle verdens skriftsprog. Med andre ord er det en liste over specielle koder, der repræsenterer næsten alle tegn på ethvert sprog. Hele Unicode-bordet er meget stort, og det er selvfølgelig ikke nødvendigt at lære det udenad. Her er en lille del af det: Udvidelse og indsnævring af primitive typer - 5 Det vigtigste er at forstå, hvordan tegn gemmes, og at huske, at hvis du kender koden for et bestemt tegn, kan du altid producere det tegn i dit program. Lad os prøve med et tilfældigt tal:

public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
Konsoloutput: 耰 Dette er formatet, der bruges til at gemme tegn i Java. Hvert symbol svarer til et tal: en 16-bit (to-byte) numerisk kode. I Unicode svarer 32816 til det kinesiske tegn 耰. Bemærk følgende punkt. I dette eksempel brugte vi en int -variabel. Den optager 32 bits i hukommelsen, mens en char optager 16. Her valgte vi en int , fordi vores nummer (32816) ikke passer i en kort . Selvom størrelsen af ​​en char (ligesom en short ) er 16 bit, er der ingen negative tal i char- området, så den "positive" del af charrækkevidden er dobbelt så stor (65536 i stedet for 32767 for den korte type). Vi kan bruge en int , så længe vores kode forbliver under 65536. Men hvis du opretter en int- værdi større end 65536, så vil den optage mere end 16 bit. Og dette vil resultere i en indsnævrende konvertering

char c = (char) x;
de ekstra bits vil blive kasseret (som diskuteret ovenfor), og resultatet vil være ret uventet.

Særlige funktioner ved tilføjelse af tegn og heltal

Lad os se på et usædvanligt eksempel:

public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i + c);
   }
}
Konsoludgang: 50 O_О Hvordan giver det mening? 1+1. Hvor kom de 50 fra?! Du ved allerede, at charværdier er gemt i hukommelsen som tal i området fra 0 til 65536, og at disse tal er en Unicode-repræsentation af et tegn. Udvidelse og indsnævring af primitive typer - 6 Når vi tilføjer et tegn og en eller anden heltalstype, konverteres tegnet til det tilsvarende Unicode-nummer. I vores kode, da vi tilføjede 1 og '1', blev symbolet '1' konverteret til sin egen kode, som er 49 (du kan bekræfte dette i tabellen ovenfor). Derfor er resultatet 50. Lad os endnu en gang tage vores gamle ven 耰 som eksempel, og prøve at tilføje det til et eller andet tal.

public static void main(String[] args) {

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

   System.out.println(c + x);
}
Konsol output: 33016 Vi har allerede opdaget, at 耰 svarer til 32816. Og når vi tilføjer dette tal og 200, får vi vores resultat: 33016. :) Som du kan se, er algoritmen her ret simpel, men du skal ikke glemme den .
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION