[JAVA] Point 61: Préférez les types primitifs aux primitives encadrées

61. Vous devez sélectionner le type primitif dans le type primitif encadré.

Différence entre le type primitif encadré et le type primitif

Comme mentionné au point 6, la différence entre le type primitif encadré (ci-après primitif encadré) et le type primitif (ci-après primitif) est ambiguë en raison de la boxing automatique et du déballage automatique. Cependant, il existe des différences entre les deux et vous devez être conscient des différences lors de leur utilisation. Il y a trois différences

Exemple d'erreur lors de l'utilisation d'une primitive encadrée

La primitive n'a qu'une valeur, mais la primitive encadrée a une référence différente de la valeur

À première vue, le code ci-dessous ressemble à une méthode qui fait une bonne comparaison.

// Broken comparator - can you spot the flaw?
Comparator<Integer> naturalOrder =
    (i, j) -> (i < j) ? -1 : (i == j ? 0 : 1);

Cependant, si vous utilisez cette méthode comme `` naturalOrder.compare (new Integer (42), new Integer (42)) '', elle doit renvoyer 0 car elle est supposée être égale, mais elle renvoie en fait 1. .. Le premier jugement (i <j) est automatiquement déballé et fonctionne correctement. D'autre part, le deuxième jugement (i == j) regarde la même valeur, c'est-à-dire si les références sont les mêmes. Par conséquent, cette comparaison n'est pas vraie et 1 est renvoyé en conséquence. Il est généralement erroné d'utiliser l'opérateur == pour les primitives encadrées.

Pour éviter l'erreur ci-dessus, utilisez `` Comparator.naturalOrder () '', ou si vous écrivez votre propre comparateur, faites une comparaison primitive comme suit.

Comparator<Integer> naturalOrder = (iBoxed, jBoxed) -> {
    int i = iBoxed, j = jBoxed; // Auto-unboxing
    return i < j ? -1 : (i == j ? 0 : 1);
};

Une primitive ne peut avoir qu'une valeur fonctionnelle, mais une primitive encadrée peut avoir une valeur nulle (valeur non fonctionnelle)

Dans le programme suivant, nullpo se produit.

package tryAny.effectiveJava;

public class BoxedPrimitive {
    static Integer i;

    public static void main(String[] args) {
        if (i == 42)
            System.out.println("Unbelievable");
    }

}

À i == 47, Integer et int sont comparés. Dans un processus où les primitives boxées et primitives sont mélangées, ** Dans la plupart des cas, la primitive boxée est automatiquement déballée. ** ** Le déballage d'un objet qui référence null provoque nullpo, ce qui se produit ici.

primitive est meilleure en termes de temps et d'espace mémoire

Ce qui suit est le programme géré dans Item6.

package tryAny.effectiveJava;

public class BoxedPrimitive2 {
    // Hideously slow program! Can you spot the object creation?
    public static void main(String[] args) {
        Long sum = 0L;
        for (long i = 0; i < Integer.MAX_VALUE; i++) {
            sum += i;
        }
        System.out.println(sum);
    }

}

C'est beaucoup plus lent que lorsque le type de variable locale est défini sur long, car le boxing et le déballage se produisent à plusieurs reprises.

Résumé

Il y avait trois problèmes, les deux premiers avaient de mauvais résultats et le dernier avait de mauvaises performances.

Il existe les cas suivants lors de l'utilisation de la primitive encadrée.

Recommended Posts

Point 61: Préférez les types primitifs aux primitives encadrées
Élément 89: Pour le contrôle d'instance, préférez les types enum à readResolve
Élément 28: Préférer les listes aux tableaux
Rubrique 65: Préférez les interfaces à la réflexion
Rubrique 43: Préférez les références de méthode aux lambdas
Élément 39: Préférez les annotations aux modèles de dénomination
Point 85: Préférez les alternatives à la sérialisation Java
Point 41: Utiliser les interfaces de marqueurs pour définir les types
Point 58: Préférez les boucles for-each aux boucles for traditionnelles
Élément 23: Préférez les hiérarchies de classes aux classes balisées
Élément 81: Préférez les utilitaires de concurrence pour attendre et notifier
Élément 80: Préférez les exécuteurs, les tâches et les flux aux threads
Élément 47: Préférez la collecte au flux comme type de retour
Point 29: Favoriser les types génériques