1. Typecasten

Typecasting in Java

Variabelen van primitieve typen (met uitzondering van het booleantype) worden gebruikt om verschillende soorten getallen op te slaan. Hoewel de typen variabelen nooit zijn veranderd, is er een plek waar u van het ene type naar het andere kunt converteren. En die plek is opdracht .

Variabelen van verschillende typen kunnen aan elkaar worden toegewezen. Wanneer u dit doet, wordt de waarde van een variabele van het ene type geconverteerd naar een waarde van een ander type en toegewezen aan de tweede variabele. In dit opzicht kunnen we twee soorten typeconversie onderscheiden: verbreding en vernauwing.

Verbreding is als het verplaatsen van een waarde van een kleine mand naar een grote: deze operatie is naadloos en pijnloos. Vernauwing vindt plaats wanneer u een waarde van een grote mand naar een kleine verplaatst: er is misschien niet genoeg ruimte en u moet iets weggooien.

Hier zijn de soorten, gesorteerd op maat mand:

Typecasten in Java 2


2. Verbreding type conversies

Het is vaak nodig om een ​​variabele van het ene numerieke type toe te wijzen aan een variabele van een ander numeriek type. Hoe doe je dat?

Java heeft 4 typen gehele getallen:

Type Maat
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Variabelen die zijn opgeslagen in kleinere korven kunnen altijd worden toegewezen aan variabelen die zijn opgeslagen in grotere korven.

int, shorten bytevariabelen kunnen eenvoudig aan longvariabelen worden toegewezen. shorten bytevariabelen kunnen worden toegewezen aan intvariabelen. En bytevariabelen kunnen aan shortvariabelen worden toegewezen.

Voorbeelden:

Code Beschrijving
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Deze code zal prima compileren.

Zo'n conversie, van een kleiner naar een groter type, wordt een verbredende typeconversie genoemd.

Hoe zit het met echte cijfers?

Bij hen is alles hetzelfde - grootte is belangrijk:

Type Maat
float 4 bytes
double 8 bytes

floatdoublevariabelen kunnen probleemloos aan variabelen worden toegewezen . Maar dingen zijn interessanter met de integer-types.

U kunt elke variabele met een geheel getal aan een variabele toewijzen float. Zelfs het longtype, dat 8 bytes lang is. En u kunt wat u maar wilt - elke variabele met een geheel getal of floatvariabele - toewijzen aan een doublevariabele:

Code Opmerking
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Houd er rekening mee dat het converteren naar een echt type kan leiden tot verlies van precisie vanwege het ontbreken van voldoende significante cijfers.

Bij het converteren van gehele getallen naar getallen met drijvende komma kunnen de lagere orde delen van getallen worden weggegooid. Maar aangezien breukgetallen geacht worden geschatte waarden op te slaan, zijn dergelijke toewijzingsbewerkingen toegestaan.


3. Beperkende typeconversies

Hoe zit het met de andere mogelijkheden? longWat als u een waarde aan een variabele moet toekennen int?

Stel je een variabele voor als een mandje. We hebben manden van verschillende groottes: 1, 2, 4 en 8 bytes. Het is geen probleem om appels over te hevelen van een kleinere mand naar een grotere. Maar bij het overschakelen van een grotere mand naar een kleinere kan er een deel van de appels verloren gaan.

Deze transformatie - van een groter type naar een kleiner type - wordt een vernauwende typeconversie genoemd . Bij het uitvoeren van een dergelijke toewijzingsbewerking kan een deel van een getal eenvoudigweg niet in de nieuwe variabele passen en daarom worden weggegooid.

Bij het verkleinen van een type moeten we de compiler expliciet vertellen dat we geen fout maken, dat we opzettelijk een deel van het nummer weggooien. Hiervoor wordt de typecast-operator gebruikt. Het is een typenaam tussen haakjes .

In dergelijke situaties vereist de Java-compiler dat de programmeur de typecast-operator opgeeft. Over het algemeen ziet het er zo uit:

(type) expression

Voorbeelden:

Code Beschrijving
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Telkens moet de typecast-operator expliciet worden aangegeven

Hier ais gelijk aan 1, en misschien lijkt de typecast-operator overdreven. Maar wat als aze groter waren?

Code Beschrijving
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

Een miljoen past perfect in een longen in een int. Maar bij het toewijzen van een miljoen aan een shortvariabele, worden de eerste twee bytes weggegooid en blijven alleen de laatste twee bytes behouden. En bij het toewijzen aan a byteis het enige dat overblijft de laatste byte.

Hoe de nummers in het geheugen zijn gerangschikt:

Type Binaire notatie Decimale notatie
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

chartype

A neemt char, net als a short, twee bytes in beslag, maar om de ene naar de andere te converteren, moet u altijd een typecast-operator gebruiken. Het probleem hier is dat het type is ondertekend en waarden van tot shortkan bevatten , maar dat het type niet is ondertekend en waarden van tot kan bevatten .-32,768+32,767char065,535

Negatieve getallen kunnen niet worden opgeslagen in een char, maar wel in een short. En een shortkan geen getallen opslaan die groter zijn dan 32,767, maar dergelijke getallen kunnen wel worden opgeslagen in een char.


4. Type van een uitdrukking

Wat als variabelen van verschillende typen in dezelfde uitdrukking worden gebruikt? Logischerwijs begrijpen we dat ze eerst omgezet moeten worden naar een gangbaar type. Maar welke?

Naar de grotere natuurlijk.

Java converteert altijd naar het grotere type. Ruwweg wordt een van het type eerst verbreed en pas daarna wordt de bewerking uitgevoerd met waarden van hetzelfde type.

Als an inten a betrokken zijn bij een uitdrukking, wordt longde waarde van de geconverteerd naar a en alleen dan gaat de bewerking verder:intlong

Code Beschrijving
int a = 1;
long b = 2;
long c = a + b;
azal worden verbreed tot a longen dan zal de toevoeging plaatsvinden.

Drijvende-kommagetallen

Als een geheel getal en een getal met drijvende komma ( floatof double) betrokken zijn bij een uitdrukking, wordt het gehele getal geconverteerd naar een getal met drijvende komma ( floatof double) en pas dan wordt de bewerking uitgevoerd.

Als de bewerking a floaten a betreft, wordt doublede geconverteerd naar a . Wat eigenlijk verwacht wordt.floatdouble

Verrassing

De typen byte, short, en charworden altijd geconverteerd naar intwanneer ze met elkaar communiceren. Er is een goede reden waarom het inttype wordt beschouwd als het standaard integer-type.

byteAls je a met a vermenigvuldigt short, krijg je een int. byteAls je a met a vermenigvuldigt byte, krijg je een int. Zelfs als je a byteen a toevoegt byte, krijg je een int.

Hiervoor zijn verschillende redenen. Voorbeelden:

Code Beschrijving
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120is 13,200, wat iets groter is dan de maximale waarde van het bytetype:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120is 230, wat ook iets groter is dan de maximale waarde van het bytetype:127

Over het algemeen krijgen we bij het vermenigvuldigen van een 8-bits (1 byte) getal met een 8-bits (1 byte) getal een getal dat 16 bits bits (2 bytes) in beslag neemt

Als gevolg hiervan worden alle bewerkingen met typen gehele getallen die kleiner zijn dan intaltijd onmiddellijk geconverteerd naar ints. En dat betekent dat als je het resultaat van de berekening wilt opslaan in een variabele van een type dat kleiner is dan een int, je altijd expliciet de typecast-operator moet specificeren.

Voorbeelden:

Code Beschrijving
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
De byte * byteuitdrukking wordt eenint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
De byte + byteuitdrukking wordt eenint
byte a = 1;
byte b = (byte) (a + 1);
De byte + intexpressie zal een zijn int
. De letterlijke is een int.

5. Een belangrijke nuance

De typecast-operator heeft een vrij hoge prioriteit.

Dat betekent dat als een expressie bijvoorbeeld optelling en een typecast-operator bevat, de typecast vóór de optelling wordt uitgevoerd.

Voorbeeld:

Code Beschrijving
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
De typecast-operator wordt alleen toegepast op de avariabele, die al een byte. Deze code wordt niet gecompileerd.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Dit is de juiste manier.

Als u de volledige uitdrukking wilt converteren naar een specifiek type, en niet slechts één component van de uitdrukking, plaatst u de gehele uitdrukking tussen haakjes en plaatst u de typecast-operator ervoor.