Conversions primitives Java

1. Introduction

Java est un langage typé, ce qui signifie qu'il utilise le concept de types. Il existe deux groupes de types distincts:

  1. types de données primitifs
  2. types de données abstraites.

Dans cet article, nous nous concentrerons sur les conversions de types primitifs.

2. Présentation des primitives

La première chose que nous devons savoir est quel type de valeurs peut être utilisé avec les types primitifs. Il existe huit types primitifs qui sont:

  • octet - 8 bits et signé

  • court - 16 bits et signé

  • char - 16 bits et non signé, de sorte qu'il puisse représenter des caractères Unicode

  • int - 32 bits et signé

  • long - 64 bits et signé

  • float - 32 bits et signé

  • double - 64 bits et signé

  • booléen - ce n'est pas numérique, ne peut avoir que des valeurs vraies ou fausses

Ce n'est pas destiné à être une discussion approfondie sur les primitives et nous parlerons un peu plus de leurs détails au besoin pendant les conversions.

3. Élargissement des conversions primitives

Lorsque nous avons besoin de convertir à partir d'une primitive plus simple ou plus petite que le type de destination, nous n'avons pas besoin d'utiliser de notation spéciale pour cela:

int myInt = 127; long myLong = myInt;

Pendant la conversion d'élargissement, la valeur primitive la plus petite est placée sur un conteneur plus grand, ce qui signifie que tout l'espace supplémentaire, à gauche de la valeur, est rempli de zéros. Cela peut également être utilisé pour passer du groupe entier à la virgule flottante:

float myFloat = myLong; double myDouble = myLong;

Ceci est possible car le passage à une primitive plus large ne perd aucune information.

4. Réduction de la conversion primitive

Parfois, nous devons ajuster une valeur plus grande que le type utilisé dans la déclaration de variable. Cela peut entraîner une perte d'informations car certains octets devront être ignorés.

Dans ce cas, nous devons exprimer explicitement que nous sommes conscients de la situation et nous sommes d'accord avec cela, en utilisant un casting:

int myInt = (int) myDouble; byte myByte = (byte) myInt;

5. Élargissement et rétrécissement de la conversion primitive

Cette situation se produit dans un cas très spécifique lorsque l' on veut convertir un octet à un omble chevalier . La première conversion est l'élargissement de l' octet à int , puis à partir de int, il est réduit à char .

Un exemple clarifiera ce point:

byte myLargeValueByte = (byte) 130; //0b10000010 -126

La représentation binaire de 130 est la même pour -126, la différence est l'interprétation du bit de signal. Convertissons maintenant d' octets à charbon :

char myLargeValueChar = (char) myLargeValueByte; //0b11111111 10000010 unsigned value int myLargeValueInt = myLargeValueChar; //0b11111111 10000010 65410

La représentation char est une valeur Unicode, mais la conversion en un int nous a montré une très grande valeur qui a les 8 bits inférieurs exactement les mêmes que -126.

Si nous le convertissons à nouveau en octet, nous obtenons:

byte myOtherByte = (byte) myLargeValueInt; //0b10000010 -126

La valeur originale que nous avons utilisée. Si tout le code commençait avec un ombles les valeurs seront différentes:

char myLargeValueChar2 = 130; //This is an int not a byte! //0b 00000000 10000010 unsigned value int myLargeValueInt2 = myLargeValueChar2; //0b00000000 10000010 130 byte myOtherByte2 = (byte) myLargeValueInt2; //0b10000010 -126

Bien que la représentation d' octet soit la même, soit -126, la représentation char nous donne deux caractères différents.

6. Conversion de boxe / déballage

En Java, nous avons une classe Wrapper pour chaque type primitif, c'est une façon intelligente de fournir aux programmeurs des méthodes de traitement utiles, sans la surcharge d'avoir tout comme une référence d'objet lourde. Depuis Java 1.5, la capacité de convertir automatiquement depuis / vers une primitive vers un objet et inversement a été incluse et obtenue par une simple attribution:

Integer myIntegerReference = myInt; int myOtherInt = myIntegerReference;

7. Conversions de chaînes

Tous les types primitifs peuvent être convertis en String via leurs classes Wrapper, qui remplacent la méthode toString () :

String myString = myIntegerReference.toString();

Si nous devons revenir à un type primitif, nous devons utiliser une méthode d'analyse définie par la classe Wrapper correspondante:

byte myNewByte = Byte.parseByte(myString); short myNewShort = Short.parseShort(myString); int myNewInt = Integer.parseInt(myString); long myNewLong = Long.parseLong(myString); float myNewFloat = Float.parseFloat(myString); double myNewDouble = Double.parseDouble(myString); 
boolean myNewBoolean = Boolean.parseBoolean(myString);

The only exception here is the Character Class because a String is made of chars anyway, this way, considering that probably the String is made of a single char, we can use the charAt() method of the String class:

char myNewChar = myString.charAt(0);

8. Numeric Promotions

To execute a binary operation, it is necessary that both operands are compatible in terms of size.

There is a set of simple rules that apply:

  1. If one of the operands is a double, the other is promoted to double
  2. Otherwise, if one of the operands is a float, the other is promoted to float
  3. Sinon, si l'un des opérandes est un long , l'autre est promu en long
  4. Sinon, les deux sont considérés comme int

Voyons un exemple:

byte op1 = 4; byte op2 = 5; byte myResultingByte = (byte) (op1 + op2);

Les deux opérandes ont été promus en int et le résultat doit être à nouveau converti en octet .

9. Conclusion

La conversion entre les types est une tâche très courante dans les activités de programmation quotidiennes. Il existe un ensemble de règles qui régissent la manière dont les langues à typage statique opèrent ces conversions. Connaître ces règles peut gagner beaucoup de temps lorsque vous essayez de comprendre pourquoi un certain code est en train de se compiler ou non.

Le code utilisé dans cet article se trouve à l'adresse over sur GitHub.