Recherche…


Introduction

Les 8 types de données primitifs byte , short , int , long , char , boolean , float et double sont les types qui stockent la plupart des données numériques brutes dans les programmes Java.

Syntaxe

  • int aInt = 8; // La partie définissant (nombre) de cette déclaration int est appelée un littéral.

  • int hexInt = 0x1a; // = 26; Vous pouvez définir des littéraux avec des valeurs hexadécimales préfixées par 0x .

  • int binInt = 0b11010; // = 26; Vous pouvez également définir des littéraux binaires; préfixé avec 0b .

  • long goodLong = 10000000000L; // Par défaut, les littéraux entiers sont de type int. En ajoutant le L à la fin du littéral, vous indiquez au compilateur que le littéral est long. Sans cela, le compilateur émettrait une erreur "nombre entier trop grand".

  • double aDouble = 3,14; // Les littéraux à virgule flottante sont de type double par défaut.

  • float aFloat = 3.14F; // Par défaut, ce littéral aurait été un double (et provoqué une erreur "Types incompatibles"), mais en ajoutant un F, nous indiquons au compilateur qu'il s'agit d'un flottant.

Remarques

Java a 8 types de données primitifs , à savoir boolean , byte , caractères short , char , int , long , float et double . (Tous les autres types sont des types de référence . Cela inclut tous les types de tableau et les types / classes d'objets intégrés qui ont une signification particulière dans le langage Java; par exemple, String , Class et Throwable et ses sous-classes.)

Le résultat de l' ensemble des opérations (addition, soustraction, multiplication, etc) sur un type primitif est au moins un int , ajoutant ainsi un short à un short produit un int , tout comme l' ajout d' un byte d'un byte , ou une char à une char . Si vous souhaitez affecter le résultat à une valeur du même type, vous devez le lancer. par exemple

byte a = 1;
byte b = 2;
byte c = (byte) (a + b);

Ne pas lancer l'opération entraînera une erreur de compilation.

Cela est dû à la partie suivante de Java Language Spec, §2.11.1 :

Un compilateur encode des charges de valeurs littérales de types byte et short utilisant des instructions Java Virtual Machine qui étendent ces valeurs aux valeurs de type int à la compilation ou à l'exécution. Les charges de valeurs littérales des types boolean et char sont codées en utilisant des instructions qui étendent le littéral à zéro à une valeur de type int à la compilation ou à l'exécution. [..]. Ainsi, la plupart des opérations sur les valeurs des types réels boolean , byte , char et short sont effectuées correctement par des instructions fonctionnant sur des valeurs de type computational int .

La raison derrière cela est également spécifiée dans cette section:

Étant donné la taille de l'opcode un octet de la machine virtuelle Java, les types d'encodage en opcodes exercent une pression sur la conception de son jeu d'instructions. Si chaque instruction typée prenait en charge tous les types de données d'exécution de la machine virtuelle Java, il y aurait plus d'instructions que celles pouvant être représentées dans un byte . [...] Des instructions distinctes peuvent être utilisées pour convertir entre des types de données non pris en charge et pris en charge, selon les besoins.

La primitive int

Un type de données primitif tel que int contient des valeurs directement dans la variable qui l'utilise, tandis qu'une variable déclarée à l'aide d' Integer contient une référence à la valeur.

Selon l' API java : "La classe Integer encapsule une valeur du type primitif int dans un objet. Un objet de type Integer contient un seul champ dont le type est int."

Par défaut, int est un entier signé 32 bits. Il peut stocker une valeur minimale de -2 31 et une valeur maximale de 2 31-1 .

int example = -42;
int myInt = 284;
int anotherInt = 73;

int addedInts = myInt + anotherInt; // 284 + 73 = 357
int subtractedInts = myInt - anotherInt; // 284 - 73 = 211

Si vous devez stocker un nombre en dehors de cette plage, utilisez plutôt long . Le dépassement de la plage de valeurs de int conduit à un dépassement d'entier, ce qui entraîne l'ajout de la valeur supérieure à la plage sur le site opposé de la plage (le positif devient négatif et vice versa). La valeur est ((value - MIN_VALUE) % RANGE) + MIN_VALUE ou ((value + 2147483648) % 4294967296) - 2147483648

int demo = 2147483647; //maximum positive integer
System.out.println(demo); //prints 2147483647
demo = demo + 1; //leads to an integer overflow
System.out.println(demo); // prints -2147483648

Les valeurs maximales et minimales de int peuvent être trouvées à:

int high = Integer.MAX_VALUE;    // high == 2147483647
int low = Integer.MIN_VALUE;     // low == -2147483648

La valeur par défaut d'un int est 0

int defaultInt;    // defaultInt == 0

La courte primitive

Un short - short est un entier signé de 16 bits. Il a une valeur minimale de 15 -2 (-32 768), et une valeur maximale de 2 15 -1 (32767)

short example = -48;
short myShort = 987;
short anotherShort = 17;

short addedShorts = (short) (myShort + anotherShort); // 1,004
short subtractedShorts = (short) (myShort - anotherShort); // 970

Les valeurs maximales et minimales de short peuvent être trouvées à:

short high = Short.MAX_VALUE;        // high == 32767
short low = Short.MIN_VALUE;         // low == -32768

La valeur par défaut d'un short est 0

short defaultShort;    // defaultShort == 0

La longue primitive

Par défaut, long est un entier signé de 64 bits (dans Java 8, il peut être signé ou non signé). Signé, il peut stocker une valeur minimale de -2 63 , et une valeur maximale de 2 63 - 1, et non signé il peut stocker une valeur minimale de 0 et une valeur maximale de 2 64 - 1

long example = -42;
long myLong = 284;
long anotherLong = 73;

//an "L" must be appended to the end of the number, because by default,
//numbers are assumed to be the int type. Appending an "L" makes it a long
//as 549755813888 (2 ^ 39) is larger than the maximum value of an int (2^31 - 1),
//"L" must be appended 
long bigNumber = 549755813888L;

long addedLongs = myLong + anotherLong; // 284 + 73 = 357
long subtractedLongs = myLong - anotherLong; // 284 - 73 = 211

Les valeurs maximales et minimales de long peuvent être trouvées à:

long high = Long.MAX_VALUE;    // high == 9223372036854775807L
long low = Long.MIN_VALUE;     // low == -9223372036854775808L

La valeur par défaut d'un long est 0L

long defaultLong;    // defaultLong == 0L

Note: la lettre "L" ajoutée à la fin du littéral long est insensible à la casse, mais il est conseillé d’utiliser le majuscule car il est plus facile de le distinguer du chiffre 1:

2L == 2l;            // true

Avertissement: Java met en cache les instances d'objets entiers de la plage allant de -128 à 127. Le raisonnement est expliqué ici: https://blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof

Les résultats suivants peuvent être trouvés:

Long val1 = 127L;
Long val2 = 127L;

System.out.println(val1 == val2); // true

Long val3 = 128L;
Long val4 = 128L;

System.out.println(val3 == val4); // false

Pour comparer correctement 2 valeurs longues d'objet, utilisez le code suivant (à partir de Java 1.7):

Long val3 = 128L;
Long val4 = 128L;

System.out.println(Objects.equal(val3, val4)); // true

Comparer une longueur primitive à un objet long n'entraînera pas de faux négatif, par exemple en comparant 2 objets à ==.

La primitive booléenne

Un boolean peut stocker une des deux valeurs, true ou false

boolean foo = true;
System.out.println("foo = " + foo);                // foo = true

boolean bar = false;
System.out.println("bar = " + bar);                // bar = false

boolean notFoo = !foo;
System.out.println("notFoo = " + notFoo);          // notFoo = false

boolean fooAndBar = foo && bar;
System.out.println("fooAndBar = " + fooAndBar);    // fooAndBar = false

boolean fooOrBar = foo || bar;
System.out.println("fooOrBar = " + fooOrBar);      // fooOrBar = true

boolean fooXorBar = foo ^ bar;
System.out.println("fooXorBar = " + fooXorBar);    // fooXorBar = true

La valeur par défaut d'un boolean est false

boolean defaultBoolean;    // defaultBoolean == false

La primitive d'octet

Un byte est un entier signé de 8 bits. Il peut stocker une valeur minimale de -2 7 (-128) et une valeur maximale de 2 7 - 1 (127)

byte example = -36;
byte myByte = 96;
byte anotherByte = 7;

byte addedBytes = (byte) (myByte + anotherByte); // 103
byte subtractedBytes = (byte) (myBytes - anotherByte); // 89

Les valeurs maximales et minimales de l' byte sont disponibles à l'adresse suivante:

byte high = Byte.MAX_VALUE;        // high == 127
byte low = Byte.MIN_VALUE;         // low == -128

La valeur par défaut d'un byte est 0

byte defaultByte;    // defaultByte == 0

La primitive float

Un float est un nombre à virgule flottante IEEE 754 32 bits à simple précision. Par défaut, les décimales sont interprétées comme des doubles. Pour créer un float , ajoutez simplement un f au littéral décimal.

double doubleExample = 0.5;      // without 'f' after digits = double
float floatExample = 0.5f;       // with 'f' after digits    = float

float myFloat = 92.7f;           // this is a float...
float positiveFloat = 89.3f;     // it can be positive,
float negativeFloat = -89.3f;    // or negative
float integerFloat = 43.0f;      // it can be a whole number (not an int)
float underZeroFloat = 0.0549f;  // it can be a fractional value less than 0

Les flotteurs gèrent les cinq opérations arithmétiques courantes: addition, soustraction, multiplication, division et module.

Remarque: Les erreurs suivantes peuvent légèrement varier. Certains résultats ont été arrondis pour des raisons de clarté et de lisibilité (le résultat imprimé de l'exemple d'addition était en fait 34.600002).

// addition
float result = 37.2f + -2.6f;  // result: 34.6

// subtraction
float result = 45.1f - 10.3f;    // result: 34.8

// multiplication
float result = 26.3f * 1.7f;   // result: 44.71

// division
float result = 37.1f / 4.8f;   // result: 7.729166

// modulus
float result = 37.1f % 4.8f;   // result: 3.4999971

En raison de la façon dont les nombres à virgule flottante sont stockés (c'est-à-dire sous forme binaire), de nombreux nombres n'ont pas de représentation exacte.

float notExact = 3.1415926f;
System.out.println(notExact); // 3.1415925

Bien que l'utilisation de float soit appropriée pour la plupart des applications, ni float ni double ne doivent être utilisés pour stocker des représentations exactes de nombres décimaux (comme des montants monétaires) ou des nombres nécessitant une plus grande précision. Au lieu de cela, la classe BigDecimal doit être utilisée.

La valeur par défaut d'un float est 0.0f .

float defaultFloat;    // defaultFloat == 0.0f

Un float est précis à environ une erreur de 1 sur 10 millions.

Remarque: Float.POSITIVE_INFINITY , Float.NEGATIVE_INFINITY , Float.NaN sont des valeurs float . NaN signifie les résultats des opérations qui ne peuvent pas être déterminés, tels que la division de 2 valeurs infinies. De plus, 0f et -0f sont différents, mais == donne une valeur vraie:

float f1 = 0f;
float f2 = -0f;
System.out.println(f1 == f2); // true
System.out.println(1f / f1); // Infinity
System.out.println(1f / f2); // -Infinity
System.out.println(Float.POSITIVE_INFINITY / Float.POSITIVE_INFINITY); // NaN

La double primitive

Un double est un nombre à virgule flottante IEEE 754 64 bits à double précision.

double example = -7162.37;
double myDouble = 974.21;
double anotherDouble = 658.7;

double addedDoubles = myDouble + anotherDouble; // 315.51
double subtractedDoubles = myDouble - anotherDouble; // 1632.91

double scientificNotationDouble = 1.2e-3;    // 0.0012

En raison de la façon dont les nombres à virgule flottante sont stockés, beaucoup de nombres n'ont pas de représentation exacte.

double notExact = 1.32 - 0.42; // result should be 0.9
System.out.println(notExact); // 0.9000000000000001

Bien que l'utilisation du double soit appropriée pour la plupart des applications, ni float ni double ne doivent être utilisés pour stocker des chiffres précis tels que la devise. Au lieu de cela, la classe BigDecimal doit être utilisée

La valeur par défaut d'un double est 0.0d

public double defaultDouble;    // defaultDouble == 0.0

Remarque: Double.POSITIVE_INFINITY , Double.NEGATIVE_INFINITY , Double.NaN sont double valeurs double . NaN signifie les résultats des opérations qui ne peuvent pas être déterminés, tels que la division de 2 valeurs infinies. De plus, 0d et -0d sont différents, mais == donne une valeur vraie:

double d1 = 0d;
double d2 = -0d;
System.out.println(d1 == d2); // true
System.out.println(1d / d1); // Infinity
System.out.println(1d / d2); // -Infinity
System.out.println(Double.POSITIVE_INFINITY / Double.POSITIVE_INFINITY); // NaN

La primitive char

Un char peut stocker un seul caractère Unicode 16 bits. Un littéral de caractère est placé entre guillemets simples

char myChar = 'u';
char myChar2 = '5';
char myChar3 = 65; // myChar3 == 'A'

Il a une valeur minimale de \u0000 (0 dans la représentation décimale, également appelée le caractère nul ) et une valeur maximale de \uffff ( \uffff ).

La valeur par défaut d'un char est \u0000 .

char defaultChar;    // defaultChar == \u0000

Afin de définir un produit de carbonisation de ' valeur d' une séquence d'échappement (caractère précédé d'une barre oblique inverse) doit être utilisée:

char singleQuote = '\'';

Il y a aussi d'autres séquences d'échappement:

char tab = '\t';
char backspace = '\b';
char newline = '\n';
char carriageReturn = '\r';
char formfeed = '\f';
char singleQuote = '\'';
char doubleQuote = '\"'; // escaping redundant here; '"' would be the same; however still allowed
char backslash = '\\';
char unicodeChar = '\uXXXX' // XXXX represents the Unicode-value of the character you want to display

Vous pouvez déclarer une char de caractère Unicode.

char heart = '\u2764';
System.out.println(Character.toString(heart)); // Prints a line containing "❤".

Il est également possible d'ajouter à un char . Par exemple, pour parcourir chaque lettre minuscule, vous pouvez effectuer les opérations suivantes:

for (int i = 0; i <= 26; i++) {
    char letter = (char) ('a' + i);
    System.out.println(letter);
}

Représentation de valeur négative

Java et la plupart des autres langages stockent des nombres intégraux négatifs dans une représentation appelée notation du complément 2 .

Pour une représentation binaire unique d'un type de données utilisant n bits, les valeurs sont codées comme suit:

Les n-1 bits les moins significatifs stockent un nombre entier positif x dans la représentation intégrale. La valeur la plus significative stocke un bit avec la valeur s . La valeur représentée par ces bits est

x - s * 2 n-1

c'est-à-dire que si le bit le plus significatif est 1, alors une valeur juste supérieure de 1 au nombre que vous pourriez représenter avec les autres bits ( 2 n-2 + 2 n-3 + ... + 2 1 + 2 0 = 2 n-1 - 1 ) est soustrait permettant une représentation binaire unique pour chaque valeur de - 2 n-1 (s = 1; x = 0) à 2 n-1 - 1 (s = 0; x = 2 n-1 - 1).

Cela a aussi l'effet secondaire agréable, que vous pouvez ajouter les représentations binaires comme s'il s'agissait de nombres binaires positifs:

v1 = x1 - s1 * 2n-1
v2 = x2 - s2 * 2n-1
s1 s2 débordement x1 + x2 résultat supplémentaire
0 0 Non x1 + x2 = v1 + v2
0 0 Oui trop grand pour être représenté avec le type de données (débordement)
0 1 Non
x1 + x2 - 2n-1 = x1 + x2 - s2 * 2n-1
= v1 + v2
0 1 Oui
(x1 + x2) mod 2n-1 = x1 + x2 - 2n-1
= v1 + v2
1 0 * voir ci-dessus (sommets de swap)
1 1 Non trop petit pour être représenté avec le type de données (x1 + x2 - 2 n <-2 n-1 ; sous - dépassement)
1 1 Oui
(x1 + x2) mod 2n-1 - 2n-1 = (x1 + x2 - 2n-1) - 2n-1
= (x1 - s1 * 2n-1) + (x2 - s2 * 2n-1)
= v1 + v2

Notez que ce fait facilite la recherche de représentation binaire de l'inverse additif (c'est-à-dire la valeur négative):

Observez que l'ajout du complément binaire au nombre a pour résultat que tous les bits sont 1. Maintenant, ajoutez 1 pour que la valeur soit dépassée et vous obtenez l'élément neutre 0 (tous les bits 0).

Donc, la valeur négative d'un nombre i peut être calculée en utilisant (en ignorant la promotion possible à int ici)

(~i) + 1

Exemple: en prenant la valeur négative de 0 ( byte ):

Le résultat de la négation 0 est 11111111 . L'ajout de 1 donne une valeur de 100000000 (9 bits). Un byte ne pouvant stocker que 8 bits, la valeur la plus à gauche est tronquée et le résultat est 00000000

Original Processus Résultat
0 (00000000) Nier -0 (11111111)
11111111 Ajouter 1 au binaire 100000000
100000000 Tronquer à 8 bits 00000000 (-0 est égal à 0)

Consommation de mémoire des primitives vs primitives en boîte

Primitif Type en boîte Taille de la mémoire de la primitive / en boîte
booléen Booléen 1 octet / 16 octets
octet Octet 1 octet / 16 octets
court Court 2 octets / 16 octets
carboniser Carboniser 2 octets / 16 octets
int Entier 4 octets / 16 octets
longue Longue 8 octets / 16 octets
flotte Flotte 4 octets / 16 octets
double Double 8 octets / 16 octets

Les objets en boîte nécessitent toujours 8 octets pour la gestion des types et de la mémoire, et comme la taille des objets est toujours un multiple de 8, les types en boîte nécessitent un total de 16 octets . En outre , chaque utilisation d'un objet en boîte implique le stockage d'une référence qui représente 4 ou 8 octets supplémentaires , en fonction des options de la machine virtuelle Java et de la machine virtuelle Java.

Dans les opérations gourmandes en données, la consommation de mémoire peut avoir un impact majeur sur les performances. La consommation de mémoire augmente encore plus lorsque vous utilisez des tableaux: un tableau float[5] ne nécessite que 32 octets; alors qu'un Float[5] stockant 5 valeurs non nulles distinctes nécessitera un total de 112 octets (sur 64 bits sans pointeurs compressés, cela augmente à 152 octets).

Caches de valeur en boîte

Les frais généraux d'espace des types encadrés peuvent être atténués dans une certaine mesure par les caches de valeur encadrés. Certains types encadrés implémentent un cache d'instances. Par exemple, par défaut, la classe Integer mettra en cache les instances pour représenter des nombres compris entre -128 et +127 . Cela ne réduit cependant pas le coût supplémentaire lié à l'indirection supplémentaire de la mémoire.

Si vous créez une instance d'un type en boîte soit par la mise en file d'attente automatique, soit en appelant la méthode statique valueOf(primitive) , le système d'exécution tente d'utiliser une valeur mise en cache. Si votre application utilise beaucoup de valeurs dans la plage mise en cache, cela peut réduire considérablement la pénalité de mémoire liée à l'utilisation de types encadrés. Certes, si vous créez des instances de valeurs encadrées "à la main", il vaut mieux utiliser valueOf plutôt que new . (La new opération crée toujours une nouvelle instance.) Si, toutefois, la majorité de vos valeurs ne se trouvent pas dans la plage mise en cache, il peut être plus rapide d'appeler new et d'enregistrer la recherche de cache.

Conversion de primitifs

En Java, nous pouvons convertir entre des valeurs entières et des valeurs à virgule flottante. En outre, étant donné que chaque caractère correspond à un numéro dans le codage Unicode, char types peuvent être convertis et des entiers et des types à virgule flottante. boolean est le seul type de données primitif qui ne peut être converti en aucun autre type de données primitif.

Il existe deux types de conversions: l’ élargissement de la conversion et la réduction de la conversion .

Une conversion élargie se produit lorsqu'une valeur d'un type de données est convertie en une valeur d'un autre type de données qui occupe plus de bits que le premier. Il n'y a pas de problème de perte de données dans ce cas.

De manière correspondante, une conversion restreinte se produit lorsqu'une valeur d'un type de données est convertie en une valeur d'un autre type de données qui occupe moins de bits que le premier. La perte de données peut se produire dans ce cas.

Java effectue automatiquement des conversions élargies. Mais si vous souhaitez effectuer une conversion restreinte (si vous êtes certain qu'aucune perte de données ne se produira), vous pouvez forcer Java à effectuer la conversion en utilisant une structure de langage appelée cast .

Conversion d'élargissement:

int a = 1;    
double d = a;    // valid conversion to double, no cast needed (widening)

Conversion rétrécie:

double d = 18.96
int b = d;       // invalid conversion to int, will throw a compile-time error
int b = (int) d; // valid conversion to int, but result is truncated (gets rounded down)
                 // This is type-casting
                 // Now, b = 18

Types de primitives

Tableau indiquant la taille et la plage de valeurs de tous les types primitifs:

Type de données représentation numérique gamme de valeurs valeur par défaut
booléen n / a faux et vrai faux
octet 8 bits signés -2 7 à 2 7 - 1 0
-128 à +127
court 16 bits signé -2 15 à 2 15 - 1 0
-32 768 à +32 767
int 32 bits signés -2 31 à 2 31 - 1 0
-2 147 483 648 à +2 147 483 647
longue 64 bits signés -2 63 à 2 63 - 1 0L
-9.223.372.036.854.775.808 à 9.223.372.036.854.775.807
flotte Virgule flottante 32 bits 1.401298464e-45 à 3.402823466e + 38 (positif ou négatif) 0,0F
double Virgule flottante 64 bits 4.94065645841246544e-324d à 1.79769313486231570e + 308d (positif ou négatif) 0.0D
carboniser 16 bits non signés 0 à 2 16 - 1 0
0 à 65,535

Remarques:

  1. La spécification de langage Java stipule que les types intégraux signés ( byte sur long ) utilisent la représentation binaire à double complément, et que les types à virgule flottante utilisent des représentations à virgule flottante binaire standard IEE 754.
  2. Java 8 et versions ultérieures fournissent des méthodes pour effectuer des opérations arithmétiques non signées sur int et long . Bien que ces méthodes permettent à un programme de traiter les valeurs des types respectifs comme non signés, les types restent des types signés.
  3. Le plus petit point flottant montré ci-dessus est sous - normal ; c'est-à-dire qu'ils ont moins de précision qu'une valeur normale . Les plus petits nombres normaux sont 1.175494351e − 38 et 2.2250738585072014e − 308
  4. Une char représente classiquement une unité de code Unicode / UTF-16.
  5. Bien qu'un boolean contienne qu'un seul bit d'information, sa taille en mémoire varie en fonction de l'implémentation de Java Virtual Machine (voir le type booléen ).


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow