JavaRush /Blog Java /Random-FR /Emballage, déballage et emballage

Emballage, déballage et emballage

Publié dans le groupe Random-FR
Bonjour! Vous connaissez déjà bien les types primitifs et avez beaucoup travaillé avec eux. Emballage, déballage et emballage - 1Les primitives en programmation, et en Java en particulier, présentent de nombreux avantages : elles occupent peu de mémoire, augmentant ainsi l'efficacité du programme, et sont clairement divisées en plages de valeurs. Cependant, au cours du processus d'apprentissage de Java, nous avons répété plus d'une fois, comme un mantra, « en Java, tout est objet ». Mais les primitifs sont une réfutation directe de ces paroles. Ce ne sont pas des objets. Alors le principe « tout est objet » est faux ? Pas vraiment. En Java, chaque type primitif a son frère jumeau, la classe wrapper ( Wrapper). Qu'est-ce qu'un emballage ? Un wrapper est une classe spéciale qui stocke la valeur d’une primitive en elle-même. Mais comme il s’agit d’une classe, elle peut créer ses propres instances. Ils stockeront les valeurs primitives nécessaires à l'intérieur, tout en étant de vrais objets. Les noms des classes wrapper sont très similaires aux noms des primitives correspondantes, ou coïncident complètement avec eux. Il sera donc très facile de s’en souvenir.
Classes wrapper pour les types de données primitifs
Types de données primitifs Classes d'emballage
int Entier
court Court
long Long
octet Octet
flotter Flotter
double Double
carboniser Personnage
booléen Booléen
Les objets de classe Wrapper sont créés comme les autres :
public static void main(String[] args) {

   Integer i = new Integer(682);

   Double d = new Double(2.33);

   Boolean b = new Boolean(false);
}
Les classes Wrapper vous permettent d’atténuer les inconvénients des types primitifs. La plus évidente est que les primitives n'ont pas de méthodes . Par exemple, ils n'ont pas de méthode toString(), vous ne pouvez donc pas, par exemple, convertir un nombre inten chaîne. Mais avec une classe wrapper, Integerc'est facile.
public static void main(String[] args) {

   Integer i = new Integer(432);

   String s = i.toString();
}
Il y aura également des difficultés avec la transformation inverse. Disons que nous avons une chaîne dont nous savons avec certitude qu’elle contient un nombre. Cependant, dans le cas d'un type primitif, intnous ne pourrons pas obtenir ce nombre à partir de la chaîne et le transformer en fait en nombre. Mais grâce aux classes wrapper, nous avons désormais cette opportunité.
public static void main(String[] args) {

   String s = "1166628";

   Integer i = Integer.parseInt(s);

   System.out.println(i);
}
Résultat : 1166628 Nous avons réussi à récupérer un nombre d'une chaîne et à l'attribuer à une variable de référence Integer i. Au fait, à propos des liens. Vous savez déjà que les paramètres sont transmis aux méthodes de différentes manières : les primitives sont transmises par valeur et les objets sont transmis par référence. Vous pouvez utiliser ces connaissances lors de la création de vos méthodes : si votre méthode fonctionne, par exemple, avec des nombres fractionnaires, mais que vous avez besoin de la logique de passage par référence, vous pouvez transmettre des paramètres à la méthode Double/Floatau lieu de double/float. De plus, en plus des méthodes, les classes wrapper ont des champs statiques très pratiques à utiliser. Par exemple, imaginez que vous soyez maintenant confronté à une tâche : imprimer le nombre maximum possible sur la console int, puis le nombre minimum possible. La tâche semble élémentaire, mais néanmoins, vous ne pourrez guère la réaliser sans Google. Et les classes wrapper vous permettent de résoudre facilement les « problèmes quotidiens » suivants :
public class Main {
   public static void main(String[] args) {

       System.out.println(Integer.MAX_VALUE);
       System.out.println(Integer.MIN_VALUE);
   }
}
De tels champs vous permettent de ne pas vous laisser distraire par des tâches plus sérieuses. Sans parler du fait que lors de l'impression du numéro 2147483647 (c'est exactement MAX_VALUE), il n'est pas surprenant de le mal saisir :) De plus, dans l'une des conférences précédentes, nous avons déjà attiré l'attention sur le fait que les objets des classes wrapper sont immuables .
public static void main(String[] args) {

   Integer a = new Integer(0);
   Integer b = new Integer(0);

   b = a;
   a = 1;
   System.out.println(b);
}
Sortie : 0 L'objet vers lequel la référence pointait à l'origine аn'a pas changé d'état, sinon la valeur baurait également changé. Comme pour String, au lieu de changer l'état de l'objet wrapper, un objet entièrement nouvel est créé en mémoire. Pourquoi les créateurs de Java ont-ils finalement décidé de conserver les types primitifs dans le langage ? Puisque tout devrait être un objet et que nous avons déjà des classes wrapper qui peuvent être utilisées pour exprimer tout ce que les primitives expriment, pourquoi ne pas simplement les laisser dans le langage et supprimer les primitives ? La réponse est simple : la performance. Les types primitifs sont appelés primitifs car ils sont dépourvus de nombreuses caractéristiques « lourdes » des objets. Oui, un objet dispose de nombreuses méthodes pratiques, mais vous n’en avez pas toujours besoin. Parfois, vous avez juste besoin du nombre 33, ou 2,62, ou de la valeur de true/ false. Dans les situations où tous les avantages des objets ne sont pas pertinents et ne sont pas nécessaires au fonctionnement du programme, les primitives feront un bien meilleur travail.

Emballage/déballage automatique

L'une des fonctionnalités des primitives et de leurs classes wrapper en Java est l'autoboxing/autounboxing. Emballage, déballage et emballage - 2 Comprenons ce concept. Comme vous et moi l'avons déjà appris plus tôt, Java est un langage orienté objet. Cela signifie que tous les programmes écrits en Java sont constitués d'objets. Les primitifs ne sont pas des objets. Cependant, la variable de classe wrapper peut se voir attribuer une valeur de type primitif. Ce processus est appelé autoboxing . De la même manière, une variable de type primitif peut se voir attribuer un objet d'une classe wrapper. Ce processus est appelé autounboxing . Par exemple:
public class Main {
   public static void main(String[] args) {
       int x = 7;
       Integer y = 111;
       x = y; // auto unpacking
       y = x * 123; // autopacking
   }
}
À la ligne 5, nous attribuons à la primitive x la valeur de y, qui est un objet de la classe wrapper Integer. Comme vous pouvez le voir, aucune action supplémentaire n'est nécessaire pour cela : le compilateur le sait intet Integer, en fait, c'est la même chose . Il s'agit d'un déballage automatique. La même chose se produit avec l'autoboxing à la ligne 6 : l'objet y se voit facilement attribuer la valeur des primitives (x*123). Ceci est un exemple d’emballage automatique. C'est pourquoi le mot « auto » est ajouté : pour attribuer des références primitives aux objets de leurs classes wrapper (et vice versa), vous n'avez rien à faire, tout se passe automatiquement . Pratique, non ? :) Une autre très grande commodité de l'auto-packing/auto-unpacking se manifeste dans le fonctionnement des méthodes. Le fait est que les paramètres de la méthode sont également soumis à l'autopacking et à l'autounpacking . Et, par exemple, si l'un d'entre eux prend deux objets en entrée Integer, on peut facilement y passer des primitives ordinaires int!
public class Main {
   public static void main(String[] args) {

       printNumber(7);//regular int, even without a variable
   }

   public static void printNumber(Integer i) {
       System.out.println("You entered a number" + i);
   }
}
Sortie : Vous avez saisi le chiffre 7. Cela fonctionne dans l'autre sens :
public class Main {
   public static void main(String[] args) {

       printNumber(new Integer(632));
   }

   public static void printNumber(int i) {
       System.out.println("You entered a number" + i);
   }
}
Un point important à retenir : l’autoboxing et unboxing ne fonctionnent pas pour les tableaux !
public class Main {
   public static void main(String[] args) {

       int[] i = {1,2,3,4,5};

       printArray(i);//error, won't compile!
   }

   public static void printArray(Integer[] arr) {
       System.out.println(Arrays.toString(arr));
   }
}
Essayer de transmettre un tableau de primitives à une méthode qui prend un tableau d'objets en entrée provoquera une erreur de compilation. Enfin, comparons encore une fois brièvement les primitives et les wrappers Primitives :
  • avoir un avantage en termes de performances
Emballages :
  • Ils permettent de ne pas violer le principe « tout est objet », afin que les nombres, symboles et valeurs booléennes vrai/faux ne sortent pas de ce concept.
  • Développez la capacité de travailler avec ces valeurs en fournissant des méthodes et des champs pratiques
  • Nécessaire lorsqu'une méthode peut fonctionner exclusivement avec des objets
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION