Bonjour! En parcourant JavaRush, vous avez rencontré plus d’une fois des types primitifs. Voici une courte liste de ce que nous savons à leur sujet :
Mais outre les valeurs, les types diffèrent également par la taille de la mémoire.
Le type
- Ce ne sont pas des objets et représentent une valeur stockée en mémoire
- Il existe plusieurs types de types primitifs :
- Nombres entiers -
byte
,short
,int
,long
- Nombres à virgule flottante (fractionnaires) -
float
etdouble
- Booléen -
boolean
- Symbolique (pour indiquer des lettres et des chiffres) -
char
- Nombres entiers -
- Chacun d'eux a sa propre plage de valeurs :
Type primitif | Taille en mémoire | Plage de valeurs |
---|---|---|
octet | 8 bits | -128 à 127 |
court | 16 bits | à -32768 à 32767 |
carboniser | 16 bits | de 0 à 65536 |
int | 32 bits | du -2147483648 au 2147483647 |
long | 64 bits | de -9223372036854775808 à 9223372036854775807 |
flotter | 32 bits | de (2 à la puissance -149) à ((2-2 à la puissance -23)*2 à la puissance 127) |
double | 64 bits | de (-2 à la puissance 63) à ((2 à la puissance 63) - 1) |
booléen | 8 (lorsqu'il est utilisé dans des tableaux), 32 (lorsqu'il est utilisé dans des non-tableaux) | vrai ou faux |
int
prend plus de byte
. A long
- plus que short
. La quantité de mémoire occupée par les primitives peut être comparée à celle des poupées gigognes : il y a de l'espace libre à l'intérieur de la poupée gigogne. Plus la poupée gigogne est grande, plus il y a d'espace. long
On peut facilement en mettre une plus petite à l'intérieur d'une grande poupée gigogne int
. Il s’adapte facilement et vous n’avez rien de plus à faire. En Java, lorsque l'on travaille avec des primitives, cela s'appelle une conversion automatique. D'une autre manière, cela s'appelle l'expansion. Voici un exemple d'extension simple :
public class Main {
public static void main(String[] args) {
int bigNumber = 10000000;
byte littleNumber = 16;
bigNumber = littleNumber;
System.out.println(bigNumber);
}
}
Ici, nous attribuons une valeur byte
à une variable int
. L'affectation a été réussie et sans aucun problème : la valeur stockée dans byte
occupe moins d'espace mémoire qu'elle ne « rentre » dans int
. La « petite poupée gigogne » (valeur byte
) s'intègre facilement dans la « grande matriochka » (variable int
). C'est une autre affaire lorsque vous essayez de faire le contraire : mettre une valeur élevée dans une variable qui n'est pas conçue pour de telles tailles. En principe, cette astuce ne fonctionnera pas avec de vraies poupées gigognes, mais en Java cela fonctionnera, mais avec des nuances. Essayons de mettre une valeur int
dans une variable short
:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = bigNumber;//error!
System.out.println(bigNumber);
}
Erreur! Le compilateur comprend que vous essayez de faire quelque chose de non standard et place une grande poupée matriochka ( int
) à l'intérieur d'une petite ( short
). Une erreur de compilation dans ce cas est un avertissement du compilateur : « Hé, tu es sûr de vouloir faire ça ? « Si vous êtes sûr, parlez-en au compilateur : « Tout va bien, je sais ce que je fais ! » " Ce processus est appelé conversion de type explicite, ou rétrécissement . Pour effectuer un rétrécissement, vous devez indiquer explicitement le type dans lequel vous souhaitez convertir votre valeur. En d’autres termes, répondez à la question du compilateur : « Eh bien, dans laquelle de ces petites poupées voulez-vous mettre cette grande poupée ? » » Dans notre cas cela ressemblera à ceci :
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = (short) bigNumber;
System.out.println(littleNumber);
}
Nous avons explicitement indiqué que nous souhaitions insérer la valeur int
dans une variable short
et en assumer la responsabilité. Le compilateur, voyant une indication explicite d'un type plus étroit, effectue une conversion. Quel sera le résultat ? Sortie de la console : -27008 Un peu inattendu. Pourquoi exactement comme ça ? C'est en fait simple. Nous avions la valeur d'origine - 10000000 Elle était stockée dans une variable int
qui occupait 32 bits, et sous forme binaire cela ressemblait à ceci : Nous écrivons cette valeur dans la variable short
, mais elle ne peut stocker que 16 bits ! En conséquence, seuls les 16 premiers bits de notre numéro y seront déplacés, le reste sera supprimé. En conséquence, la variable short
contiendra la valeur , qui sous forme décimale est exactement égale à -27008. C'est pourquoi le compilateur a « demandé une confirmation » sous la forme d'une conversion explicite vers un type spécifique. Premièrement, cela montre que vous assumez la responsabilité du résultat, et deuxièmement, cela indique au compilateur combien d'espace allouer lors de la conversion des types. Après tout, si dans le dernier exemple nous avions converti int
en type byte
, et non en short
, nous n'aurions que 8 bits à notre disposition, pas 16, et le résultat aurait été différent. Pour les types fractionnaires ( float
et double
), le rétrécissement se produit différemment. Si vous essayez de convertir un tel nombre en un type entier, sa partie fractionnaire sera ignorée.
public static void main(String[] args) {
double d = 2.7;
long x = (int) d;
System.out.println(x);
}
Sortie console : 2
Type de données char
Vous savez déjà que le type char est utilisé pour afficher des caractères individuels.public static void main(String[] args) {
char c = '!';
char z = 'z';
char i = '8';
}
Mais il présente un certain nombre de fonctionnalités qu’il est important de comprendre. Regardons à nouveau le tableau avec les plages de valeurs :
Type primitif | Taille en mémoire | Plage de valeurs |
---|---|---|
octet | 8 bits | -128 à 127 |
court | 16 bits | -32768 à 32767 |
carboniser | 16 bits | de 0 à 65536 |
int | 32 bits | du -2147483648 au 2147483647 |
long | 64 bits | de -9223372036854775808 à 9223372036854775807 |
flotter | 32 bits | de (2 à la puissance -149) à ((2-2 à la puissance -23)*2 à la puissance 127) |
double | 64 bits | de (-2 à la puissance 63) à ((2 à la puissance 63)-1) |
booléen | 8 (lorsqu'il est utilisé dans des tableaux), 32 (lorsqu'il est utilisé dans des non-tableaux) | vrai ou faux |
char
a une plage numérique de 0 à 65536. Mais qu’est-ce que cela signifie ? Après tout, char
ce ne sont pas seulement des chiffres, mais aussi des lettres, des signes de ponctuation... Le fait est que les valeurs char
sont stockées en Java au format Unicode. Nous avons déjà rencontré Unicode dans l'une des conférences précédentes. Vous vous souvenez probablement qu'Unicode est une norme de codage de caractères qui inclut des caractères de presque toutes les langues écrites du monde. En d'autres termes, il s'agit d'une liste de codes spéciaux dans laquelle se trouve un code pour presque tous les caractères de n'importe quelle langue. Le tableau général Unicode est très volumineux et, bien entendu, il n'est pas nécessaire de l'apprendre par cœur. En voici, par exemple, un extrait : L'essentiel est de comprendre le principe de stockage des valeurs char
et de se rappeler qu'en connaissant le code d'un symbole spécifique, vous pouvez toujours l'obtenir dans le programme. Essayons ceci avec un nombre aléatoire :
public static void main(String[] args) {
int x = 32816;
char c = (char) x ;
System.out.println(c);
}
Sortie de la console : Il s'agit du format dans lequel les caractères sont stockés en Java char
. Chaque caractère correspond à un nombre – un code numérique de 16 bits, soit deux octets. Unicode 32816 correspond au caractère 耰. Faites attention à ce moment. Dans cet exemple, nous avons utilisé la variable int
. Il occupe 32 bits de mémoire , tandis que char
16 . Ici, nous avons choisi car le numéro dont nous avons besoin, 32816, est hors de portée . Bien que la taille , comme short, soit de 16 bits, il n'y a pas de nombres négatifs dans la plage, donc la plage « positive » est deux fois plus grande (65536 au lieu de 32767 ). Nous pouvons utiliser , à condition que notre code soit compris entre 65536. Mais si nous créons un nombre , il occupera plus de 16 bits. Et en réduisant les types : int
short
char
char
char
short
int
int >65536
char c = (char) x;
les bits supplémentaires seront supprimés et le résultat sera tout à fait inattendu.
Caractéristiques de l'ajout de caractères et d'entiers
Regardons cet exemple inhabituel :public class Main {
public static void main(String[] args) {
char c = '1';
int i = 1;
System.out.println(i+c);
}
}
Sortie de la console : 50 O_O Où est la logique ? 1+1, d'où viennent 50 ?! Vous savez déjà que les valeurs char
sont stockées en mémoire sous forme de nombres compris entre 0 et 65536, représentant l'Unicode de notre personnage. Alors voilà. Lorsque nous effectuons une addition char
, un type entier char
est converti en nombre qui lui correspond en Unicode. Lorsque dans notre code nous avons ajouté 1 et « 1 », le symbole « 1 » a été transformé en son code, qui est 49 (vous pouvez le vérifier dans le tableau ci-dessus). Par conséquent, le résultat est devenu égal à 50. Prenons encore une fois notre vieil ami -耰comme exemple et essayons de l'ajouter avec un nombre.
public static void main(String[] args) {
char c = '耰';
int x = 200;
System.out.println(c + x);
}
Sortie de la console : 33016 Nous avons déjà découvert que cela correspond au code 32816. Et lorsque nous ajoutons ce nombre et 200, nous obtenons exactement notre résultat - 33016 :) Le mécanisme de fonctionnement, comme vous pouvez le voir, est assez simple.
GO TO FULL VERSION