CodeGym /Java blogg /Slumpmässig /Utvidgning och förträngning av primitiva typer
John Squirrels
Nivå
San Francisco

Utvidgning och förträngning av primitiva typer

Publicerad i gruppen
Hej! När du har gått igenom CodeGym har du stött på primitiva typer många gånger. Här är en kort lista över vad vi vet om dem:
  1. De är inte objekt och representerar ett värde som är lagrat i minnet
  2. Det finns flera sorter
    • Hela tal: byte , kort , int , lång
    • Flyttal (bråktal): flytande och dubbla
    • Logiska värden: booleska
    • Symboliska värden (för att representera bokstäver och siffror): char
  3. Varje typ har sitt eget värdeintervall:

Primitiv typ Storlek i minnet Värdeintervall
byte 8 bitar -128 till 127
kort 16 bitar -32768 till 32767
röding 16 bitar 0 till 65536
int 32 bitar -2147483648 till 2147483647
lång 64 bitar -9223372036854775808 till 9223372036854775807
flyta 32 bitar (2 till -149) till ((2 - (2 till -23)) * 2 till 127)
dubbel 64 bitar (-2 till 63) till ((2 till 63) - 1)
booleskt 8 (när den används i arrayer), 32 (om den inte används i arrayer) sant eller falskt
Men förutom att de har olika värden skiljer de sig också åt i hur mycket plats de upptar i minnet. En int tar mer än en byte. Och en lång är större än en kort. Mängden minne som upptas av primitiver kan jämföras med ryska häckande dockor: Utvidgning och förträngning av primitiva typer - 2 Varje häckande docka har utrymme tillgängligt inuti. Ju större häckande docka, desto mer utrymme finns. En stor häckande docka ( lång ) kommer lätt att rymma en mindre int . Den passar lätt och du behöver inte göra något annat. I Java, när man arbetar med primitiver, kallas detta implicit konvertering. Eller uttryckt annorlunda, det kallas breddning.

Utvidgning i Java

Här är ett enkelt exempel på en växande konvertering:

public class Main {

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

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
Här tilldelar vi ett bytevärde till en int -variabel. Uppdraget lyckas utan problem: värdet lagrat i en byte tar mindre minne än vad en int kan ta emot. Den lilla kapseldockan (bytevärde) får lätt plats i den stora kapseldockan ( int variabel). Det är en annan sak om man försöker göra tvärtom, dvs att sätta ett stort värde i en variabel vars intervall inte kan ta emot en så stor datatyp. Med riktiga häckande dockor skulle numret helt enkelt inte passa. Med Java kan det, men med nyanser. Låt oss försöka lägga in 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);
}
Fel! Kompilatorn förstår att du försöker göra något onormalt genom att trycka in en stor docka ( int ) inuti en liten ( kort ). I det här fallet är kompileringsfelet en varning från kompilatorn: "Hej, är du helt säker på att du vill göra det här?" Om du är säker säger du till kompilatorn: "Allt är okej. Jag vet vad jag gör!" Denna process kallas explicit typkonvertering, eller avsmalning.

Begränsning i Java

För att utföra en avsmalnande konvertering måste du uttryckligen ange vilken typ du vill konvertera ditt värde till. Med andra ord måste du svara på kompilatorns fråga: "Tja, vilken av dessa små häckande dockor vill du lägga den här stora häckdockan i?" I vårt fall ser det ut så här:

public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
Vi anger uttryckligen att vi vill lägga in en int i en kort variabel och att vi tar ansvaret. När kompilatorn ser att en smalare typ har angetts uttryckligen, utför kompilatorn konverteringen. Vad är resultatet? Konsolutgång: -27008 Det var lite oväntat. Varför fick vi det egentligen? Faktum är att det hela är väldigt enkelt. Ursprungligen var värdet 10000000. Det lagrades i en int- variabel, som upptar 32 bitar. Detta är dess binära representation:
Utvidgning och förträngning av primitiva typer - 3
Vi skriver in detta värde i en kort variabel, som bara kan lagra 16 bitar! Följaktligen kommer endast de första 16 bitarna av vårt nummer att flyttas dit. Resten kommer att kasseras. Som ett resultat får den korta variabeln följande värde
Utvidgning och förträngning av primitiva typer - 4
som i decimalform är lika med -27008 Det är därför kompilatorn ber dig att "bekräfta" genom att ange en explicit avsmalnande konvertering till en specifik typ. För det första visar detta att du tar ansvar för resultatet. Och för det andra talar den om för kompilatorn hur mycket utrymme som ska tilldelas när konvertering sker. När allt kommer omkring, i det sista exemplet, om vi tilldelade ett int-värde till en bytevariabel snarare än en kort , skulle vi bara ha 8 bitar till vårt förfogande, inte 16, och resultatet skulle bli annorlunda. Bråktyper ( float och double ) har sin egen process för att minska konverteringar. Om du försöker gjuta ett fraktionsnummer till en heltalstyp, kommer bråkdelen att kasseras.

public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
Konsolutgång: 2

röding

Du vet redan att char används för att visa enskilda tecken.

public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';
  
}
Men denna datatyp har flera funktioner som är viktiga att förstå. Låt oss titta på tabellen över värdeintervall igen:
Primitiv typ Storlek i minnet Värdeintervall
byte 8 bitar -128 till 127
kort 16 bitar -32768 till 32767
röding 16 bitar 0 till 65536
int 32 bitar -2147483648 till 2147483647
lång 64 bitar -9223372036854775808 till 9223372036854775807
flyta 32 bitar (2 till -149) till ((2 - (2 till -23)) * 2 till 127)
dubbel 64 bitar (-2 till 63) till ((2 till 63) - 1)
booleskt 8 (när den används i arrayer), 32 (om den inte används i arrayer) sant eller falskt
Intervallet 0 till 65536 anges för char- typen. Men vad betyder det? När allt kommer omkring representerar en char inte bara siffror, utan också bokstäver, skiljetecken... Saken är att i Java lagras char- värden i Unicode-format. Vi har redan stött på Unicode i en av de tidigare lektionerna. Du kommer säkert ihåg att Unicode är en teckenkodningsstandard som innehåller symbolerna för nästan alla världens skriftspråk. Med andra ord, det är en lista med specialkoder som representerar nästan varje tecken på alla språk. Hela Unicode-bordet är mycket stort, och det finns naturligtvis ingen anledning att lära sig det utantill. Här är en liten del av det: Utvidgning och förträngning av primitiva typer - 5 Det viktigaste är att förstå hur tecken lagras, och att komma ihåg att om du kan koden för ett visst tecken, kan du alltid producera det tecknet i ditt program. Låt oss försöka med något slumpmässigt tal:

public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
Konsolutgång: 耰 Detta är formatet som används för att lagra tecken i Java. Varje symbol motsvarar ett nummer: en 16-bitars (två-byte) numerisk kod. I Unicode motsvarar 32816 det kinesiska tecknet 耰. Notera följande punkt. I det här exemplet använde vi en int -variabel. Den upptar 32 bitar i minnet, medan en char upptar 16. Här valde vi en int , eftersom vårt nummer (32816) inte får plats i en kort . Även om storleken på en char (precis som en kort ) är 16 bitar, finns det inga negativa tal i char- intervallet, så den "positiva" delen av charintervallet är dubbelt så stort (65536 istället för 32767 för den korta typen). Vi kan använda en int så länge som vår kod förblir under 65536. Men om du skapar ett int- värde som är större än 65536, kommer det att uppta mer än 16 bitar. Och detta kommer att resultera i en minskande konvertering

char c = (char) x;
de extra bitarna kommer att kasseras (som diskuterats ovan) och resultatet kommer att bli ganska oväntat.

Specialfunktioner för att lägga till tecken och heltal

Låt oss titta på ett ovanligt exempel:

public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i + c);
   }
}
Konsolutgång: 50 O_О Hur är det vettigt? 1+1. Var kom de 50 ifrån?! Du vet redan att charvärden lagras i minnet som siffror i intervallet från 0 till 65536, och att dessa siffror är en Unicode-representation av ett tecken. Utvidgning och förträngning av primitiva typer - 6 När vi lägger till ett char och någon heltalstyp omvandlas char till motsvarande Unicode-nummer. I vår kod, när vi lade till 1 och '1', konverterades symbolen '1' till sin egen kod, som är 49 (du kan verifiera detta i tabellen ovan). Därför blir resultatet 50. Låt oss återigen ta vår gamla vän 耰 som exempel, och försöka lägga till det till något nummer.

public static void main(String[] args) {

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

   System.out.println(c + x);
}
Konsolutgång: 33016 Vi har redan upptäckt att 耰 motsvarar 32816. Och när vi lägger till detta nummer och 200 får vi vårt resultat: 33016. :) Som du kan se är algoritmen här ganska enkel, men du får inte glömma den .
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION