1. Transtypage
Les variables de types primitifs (à l'exception du boolean
type) 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 :
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
, short
et byte
les variables peuvent être facilement assignées aux long
variables. short
et byte
les variables peuvent être affectées à int
des variables. Et byte
les variables peuvent être affectées à short
des variables.
Exemples:
Code | Description |
---|---|
|
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 |
float
les variables peuvent être affectées à double
des 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 float
variable. Même le long
type, qui fait 8 octets de long. Et vous pouvez affecter ce que vous voulez — n'importe quelle variable entière ou float
variable — à une double
variable :
Code | Note |
---|---|
|
|
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 long
valeur à une int
variable ?
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 |
---|---|
|
Chaque fois que l'opérateur de transtypage doit être indiqué explicitement |
Ici a
est égal à 1
, et peut-être que l'opérateur de transtypage semble exagéré. Et si a
c'était plus gros ?
Code | Description |
---|---|
|
|
Un million s'inscrit parfaitement dans un long
et dans un int
. Mais lors de l'affectation d'un million à une short
variable, 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 |
char
taper
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 short
type est signé et peut contenir des valeurs de -32,768
à +32,767
, mais le char
type 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 short
ne 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 int
et a long
sont impliqués dans une expression, la valeur de int
sera convertie en a long
et alors seulement l'opération se poursuivra :
Code | Description |
---|---|
|
a sera élargi à a long , puis l'addition se produira. |
Nombres à virgule flottante
Si un entier et un nombre à virgule flottante ( float
ou double
) sont impliqués dans une expression, l'entier sera converti en un nombre à virgule flottante ( float
ou double
), et alors seulement l'opération sera effectuée.
Si l'opération implique a float
et a double
, alors le float
sera converti en a double
. Ce qui est en fait attendu.
Les types byte
, short
et char
sont toujours convertis en int
lorsqu'ils interagissent les uns avec les autres. Il y a une bonne raison pour laquelle le int
type est considéré comme le type entier standard.
Si vous multipliez a byte
par a short
, vous obtenez un int
. Si vous multipliez a byte
par a byte
, vous obtenez un int
. Même si vous ajoutez a byte
et a byte
, vous obtenez un int
.
Il y a plusieurs raisons à cela. Exemples:
Code | Description |
---|---|
|
110 * 120 est 13,200 , ce qui est légèrement supérieur à la valeur maximale du byte type :127 |
|
110 + 120 est 230 , qui est également légèrement supérieure à la valeur maximale du byte type :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 à int
sont toujours immédiatement converties en int
s. 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 |
---|---|
|
L' byte * byte expression sera unint |
|
L' byte + byte expression sera unint |
|
L' byte + int expression 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 |
---|---|
|
L'opérateur de transtypage ne sera appliqué qu'à la a variable, qui est déjà un byte . Ce code ne compilera pas. |
|
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.