1. Transtypage

Typecasting en Java

Les variables de types primitifs (à l'exception du booleantype) sont utilisées pour stocker différents types de nombres. Bien que les types de variables n'aient jamais changé, il existe un endroit où vous pouvez convertir d'un type à un autre. Et cet endroit est l'affectation .

Des variables de différents types peuvent être affectées les unes aux autres. Lorsque vous faites cela, la valeur d'une variable d'un type est convertie en une valeur d'un autre type et affectée à la deuxième variable. À cet égard, nous pouvons identifier deux types de conversion de type : l'élargissement et le rétrécissement.

L'élargissement revient à déplacer une valeur d'un petit panier vers un grand : cette opération est transparente et indolore. Le rétrécissement se produit lorsque vous déplacez une valeur d'un grand panier vers un petit : il se peut qu'il n'y ait pas assez d'espace et vous devrez jeter quelque chose.

Voici les types, triés par taille de panier :

Typecasting en Java 2


2. Conversions de type élargissement

Il est souvent nécessaire d'affecter une variable d'un type numérique à une variable d'un autre type numérique. Comment tu fais ça?

Java a 4 types d'entiers :

Taper Taille
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Les variables stockées dans des paniers plus petits peuvent toujours être affectées à des variables stockées dans des paniers plus grands.

int, shortet byteles variables peuvent être facilement assignées aux longvariables. shortet byteles variables peuvent être affectées à intdes variables. Et byteles variables peuvent être affectées à shortdes variables.

Exemples:

Code Description
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Ce code compilera très bien.

Une telle conversion, d'un type plus petit à un type plus grand, est appelée conversion de type élargissement .

Qu'en est-il des nombres réels ?

Avec eux, tout est pareil — la taille compte :

Taper Taille
float 4 bytes
double 8 bytes

floatles variables peuvent être affectées à doubledes variables sans aucun problème. Mais les choses sont plus intéressantes avec les types entiers.

Vous pouvez affecter n'importe quelle variable entière à une floatvariable. Même le longtype, qui fait 8 octets de long. Et vous pouvez affecter ce que vous voulez — n'importe quelle variable entière ou floatvariable — à une doublevariable :

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

b == 1.23456794E9
c == 1.23456789E9

Notez que la conversion en un type réel peut entraîner une perte de précision en raison du manque de chiffres significatifs suffisants.

Lors de la conversion d'entiers en nombres à virgule flottante, les parties inférieures des nombres peuvent être ignorées. Mais comme les nombres fractionnaires sont censés stocker des valeurs approximatives, de telles opérations d'affectation sont autorisées.


3. Réduction des conversions de type

Qu'en est-il des autres possibilités ? Que faire si vous avez besoin d'attribuer une longvaleur à une intvariable ?

Imaginez une variable comme un panier. Nous avons des paniers de différentes tailles : 1, 2, 4 et 8 octets. Ce n'est pas un problème de transférer des pommes d'un petit panier à un plus grand. Mais lors du passage d'un panier plus grand à un plus petit, certaines pommes peuvent être perdues.

Cette transformation — d'un type plus grand à un type plus petit — s'appelle une conversion de type resserrée . Lors de l'exécution d'une opération d'affectation comme celle-ci, une partie d'un nombre peut tout simplement ne pas tenir dans la nouvelle variable et peut donc être ignorée.

Lors de la restriction d'un type, nous devons dire explicitement au compilateur que nous ne commettons pas d'erreur, que nous supprimons délibérément une partie du nombre. L'opérateur de transtypage est utilisé pour cela. C'est un nom de type entre parenthèses .

Dans de telles situations, le compilateur Java demande au programmeur de spécifier l'opérateur de transtypage. En général, ça ressemble à ça :

(type) expression

Exemples:

Code Description
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Chaque fois que l'opérateur de transtypage doit être indiqué explicitement

Ici aest égal à 1, et peut-être que l'opérateur de transtypage semble exagéré. Et si ac'était plus gros ?

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

Un million s'inscrit parfaitement dans un longet dans un int. Mais lors de l'affectation d'un million à une shortvariable, les deux premiers octets sont ignorés et seuls les deux derniers octets sont conservés. Et lors de l'affectation à un byte, la seule chose qui reste est le dernier octet.

Comment les nombres sont arrangés en mémoire :

Taper Notation binaire Notation décimale
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

chartaper

A char, comme a short, occupe deux octets, mais pour convertir l'un en un autre, vous devez toujours utiliser un opérateur de transtypage. Le problème ici est que le shorttype est signé et peut contenir des valeurs de -32,768à +32,767, mais le chartype n'est pas signé et peut contenir des valeurs de 0à 65,535.

Les nombres négatifs ne peuvent pas être stockés dans un char, mais ils peuvent être stockés dans un short. Et a shortne peut pas stocker de nombres supérieurs à 32,767, mais ces nombres peuvent être stockés dans a char.


4. Type d'expression

Que se passe-t-il si des variables de types différents sont utilisées dans la même expression ? Logiquement, nous comprenons qu'ils doivent d'abord être convertis en un type commun. Mais lequel?

Au plus grand, bien sûr.

Java convertit toujours en type plus grand. En gros, l'un des types est d'abord élargi et ensuite seulement l'opération est effectuée en utilisant des valeurs du même type.

Si an intet a longsont impliqués dans une expression, la valeur de intsera convertie en a longet alors seulement l'opération se poursuivra :

Code Description
int a = 1;
long b = 2;
long c = a + b;
asera élargi à a long, puis l'addition se produira.

Nombres à virgule flottante

Si un entier et un nombre à virgule flottante ( floatou double) sont impliqués dans une expression, l'entier sera converti en un nombre à virgule flottante ( floatou double), et alors seulement l'opération sera effectuée.

Si l'opération implique a floatet a double, alors le floatsera converti en a double. Ce qui est en fait attendu.

Surprendre

Les types byte, shortet charsont toujours convertis en intlorsqu'ils interagissent les uns avec les autres. Il y a une bonne raison pour laquelle le inttype est considéré comme le type entier standard.

Si vous multipliez a bytepar a short, vous obtenez un int. Si vous multipliez a bytepar a byte, vous obtenez un int. Même si vous ajoutez a byteet a byte, vous obtenez un int.

Il y a plusieurs raisons à cela. Exemples:

Code Description
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120est 13,200, ce qui est légèrement supérieur à la valeur maximale du bytetype :127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120est 230, qui est également légèrement supérieure à la valeur maximale du bytetype :127

En général, en multipliant un nombre de 8 bits (1 octet) par un nombre de 8 bits (1 octet), on obtient un nombre qui occupe des bits de 16 bits (2 octets)

Par conséquent, toutes les opérations avec des types entiers inférieurs à intsont toujours immédiatement converties en ints. Et cela signifie que si vous souhaitez stocker le résultat du calcul dans une variable d'un type inférieur à un int, vous devrez toujours spécifier explicitement l'opérateur de transtypage.

Exemples:

Code Description
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
L' byte * byteexpression sera unint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
L' byte + byteexpression sera unint
byte a = 1;
byte b = (byte) (a + 1);
L' byte + intexpression sera un int
Le littéral est un int.

5. Une nuance importante

L'opérateur de transtypage a une priorité assez élevée.

Cela signifie que si une expression contient, par exemple, addition et un opérateur de transtypage, le transtypage sera effectué avant l'ajout.

Exemple:

Code Description
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
L'opérateur de transtypage ne sera appliqué qu'à la avariable, qui est déjà un byte. Ce code ne compilera pas.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
C'est la bonne façon.

Si vous souhaitez convertir l'expression entière en un type spécifique, et pas seulement un composant de l'expression, placez l'expression entière entre parenthèses et placez l'opérateur de transtypage devant.