Maison > Java > javaDidacticiel > Tapez les précautions de transfert en Java

Tapez les précautions de transfert en Java

王林
Libérer: 2024-09-12 10:16:50
original
968 Les gens l'ont consulté

Java est un langage fortement typé, mais il est toujours possible de transférer des valeurs entre des variables primitives de types différents. Par exemple, je peux attribuer la valeur d'un int à un double sans aucun problème, tant que la capacité de stockage du type recevant la valeur peut la gérer.

Voir ci-dessous la taille de chaque type primitif :

Cuidados com transferência de tipos em Java

Le transfert de valeur vers un type doté d'une plus grande capacité de stockage a un nom technique : « élargissement de la conversion ». Le terme en portugais est généralement traduit par « conversion d'élargissement » ou « conversion d'élargissement ». Il fait référence au processus dans lequel une valeur d'un type de données plus petit ou plus restreint est convertie en un type de données plus grand ou plus complet sans perte d'informations.

Mais que se passe-t-il si je souhaite transférer la valeur vers un type avec une capacité de stockage plus petite ? Le compilateur Java n'aime pas ça, mais il l'autorisera si vous le transtypez, comme dans l'exemple ci-dessous.

double decimal = 65.9;
int i = (int) decimal; //aqui ele perde a casa decimal e vira 65
char c = (char) i; //aqui ele vira a letra A (que corresponde a 65)
Copier après la connexion

Si la taille de la valeur qui ira au nouveau type dépasse les limites de ce type, quelque chose de plus dramatique peut se produire. Un int i = 10 tient dans une variable d'octet, car il contient 8 bits dans une plage de -128 à 127. Cependant, que se passe-t-il si je veux mettre un int i = 128 dans une variable de type byte... il y aura une perte d'information.

public class Main
{
    public static void main(String[] args) {
        int i = 128;
        byte b = (byte) i;

        System.out.println(b); // o valor de b agora é -128 :S
    }
}
Copier après la connexion

Boîte automatique

Dans le dernier post [lire-le ici], j'ai parlé un peu des cours Wrapper. A titre d'exemple, j'avais écrit Integer.parse(i) = imaginez que i soit un type
int primitif.

Actuellement, l'utilisation de la méthode d'analyse Wrapper n'est plus encouragée car elle est obsolète. Pour transformer une primitive en classe Wrapper et, ainsi, utiliser des méthodes intégrées, il est recommandé de faire de l'"autoboxing", comme dans l'exemple :

Character ch = 'a';
Integer i = 10;
Copier après la connexion

Notez qu’il s’agit d’une approche plus directe. Attribuez simplement la valeur en une seule fois.

Pour faire l'inverse et renvoyer les données sous forme de type primitif, vous pouvez faire le "unboxing" en utilisant la méthode valueOf:

Integer i = 10;
int j = Integer.valueOf(i);
Copier après la connexion

Faire un Wrapper à partir d'une primitive, comme je l'ai dit dans le post précédent, a l'avantage de permettre d'utiliser les méthodes de la classe et de faciliter la vie lorsqu'on travaille avec les données.

La version wrapper d'une primitive peut y ressembler beaucoup à première vue, mais la JVM ne traite pas un objet et une primitive de la même manière, ne l'oubliez pas. N'oubliez pas que les primitives vont dans la pile et les objets dans le tas [rappelez-vous ici].

En termes de performances, il est clair que récupérer les données d'une primitive est moins coûteux pour l'ordinateur, puisque la valeur est stockée directement, et non par référence. Il est beaucoup plus rapide d'obtenir un élément de données prêt à l'emploi que de continuer à rassembler les éléments en mémoire.

Mais il existe des cas où l'utilisation d'un Wrapper sera indispensable. Par exemple, lorsque vous souhaitez travailler avec la classe ArrayList. Il n'accepte que les objets comme paramètres, pas les valeurs primitives.

La flexibilité qu'apporte cette transformation de primitif en objet et vice versa est vraiment cool pour le langage. Mais nous devons être conscients de ces pièges évoqués ici et de bien d’autres.

Juste pour choquer la société (mdr) je vais donner un exemple de cas problématique impliquant le comportement inattendu d'un code lorsqu'on travaille avec une surcharge (je n'ai pas encore fait d'article sur la surcharge, mais je le ferai. En gros , la surcharge se produit lorsqu'une méthode a des signatures différentes).

Ce cas a été évoqué dans le livre "Effective Java", de Joshua Bloch.

public class SetListTest {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<>();
        List<Integer> list = new ArrayList<>();

        for (int i = -3; i < 3; i++) {
            set.add(i);
            list.add(i);
        }

        for (int i = 0; i < 3; i++) {
            set.remove(i);
            list.remove(i); // como corrigir: list.remove((Integer) i);
        }

        System.out.println(set + " " + list);

    }
Copier après la connexion

Dans ce programme, l'objectif était d'ajouter des valeurs entières de -3 à 2 [-3, -2, -1, 0, 1, 2] à un ensemble et une liste. Supprimez ensuite les valeurs positives [0, 1 et 2]. Mais si vous exécutez ce code, vous remarquerez que l’ensemble et la liste n’ont pas présenté le même résultat. L'ensemble renvoie [-3, -2, -1], comme prévu. La liste renvoie [-2, 0, 2].

Cela se produit parce que l'appel à la méthode intégrée remove(i) de la classe List traite i comme un type primitif int, et rien d'autre. La méthode, à son tour, supprime les éléments en position i.

L'appel à la méthode remove(i) de la classe Set appelle une surcharge qui reçoit un objet Integer en paramètre, convertissant automatiquement i, qui était à l'origine un int, en Integer. Le comportement de cette méthode, à son tour, exclut de l'ensemble les éléments qui ont une valeur égale à i (et non un index égal à i) - notez que le type attendu pour l'ensemble et la liste était Integer. (Définir l'ensemble / Liste de liste). C'est pourquoi la surcharge choisie pour la méthode Remove, de la classe Set, l'a convertie en Integer.

Alors que le comportement de Remove dans List consiste à supprimer par index, Remove dans Set consiste à supprimer par valeur. Tout cela est dû à la surcharge de la suppression qui reçoit Integer.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal