Analyse automatique du code source de boxe et de déballage Java
Qu'est-ce que l'emballage et le déballage ?
Le processus de conversion du type de base int en type d'emballage Integer est appelé boxing, et vice versa est appelé unboxing.
Premier coup d'œil à un morceau de code
public static void main(String[] args) { Integer a = 127, b = 127; Integer c = 128, d= 128; System.out.println(a == b); // true System.out.println(c == d); // false }
Je ne sais pas si quelqu'un d'autre ne sait pas pourquoi vrai et faux apparaissent dans ce code. À partir de là, nous introduisons le fonctionnement de la boxe Java. Nous analysons avec des questions.
Boxing (valueOf())
public static Integer valueOf(int i) { // -128 - 127 if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
Nous pouvons constater qu'il y a un jugement au début. Si la plage de valeurs est comprise entre [-128,127], alors elle sera extraite de ce cache (tableau d'entiers), sinon This. la gamme est alors directement nouvelle.
Pourquoi avons-nous besoin d'un cache de [-128,127] ?
Je comprends de quoi je parle, car dans notre métier, il peut y avoir différents champs de type entier tels que le statut et l'identification. Ces valeurssont généralement 0, 1, 2, 3 et autres, et elles. apparaissent plus fréquemment. S'il n'y a pas de cache, de nouveaux objets fréquents sont nécessaires puis libérés, ce qui consomme beaucoup d'espace mémoire, donc le cache apparaît, ce qui peut grandement nous aider à optimiser une certaine perte d'espace.
Pourquoi est-ce [-128,127] ?
J'ai jeté un œil à cela. Je n'expliquerai pas la raison spécifique ici. Cela repose principalement sur des connaissances informatiques de base. Après avoir compris ce que sont le code d'origine, le code inverse et le code complémentaire. Il est facile de savoir pourquoi il se situe dans cette fourchette.
Cette valeur peut également être modifiée via les paramètres de démarrage.
-XX:AutoBoxCacheMax=(size)
Problèmes de performances causés par la boxe automatique
Alors maintenant, vous devriez comprendre la raison pour laquelle le code ci-dessus a des résultats différents, alors y avez-vous déjà pensé, comme celui de notre entreprise Dans la boucle for, des opérations de données statistiques comme celle-ci se produisent s'il y a une boxe automatique, quels problèmes surviendront ? Regardons le morceau de code suivant.
public static void main(String[] args) { long startTime = System.currentTimeMillis(); Integer count = 0; // int count = 0; for (int i = 0; i < 5000000; i++) { count += i; } System.out.println("计算时长:" + (System.currentTimeMillis() - startTime) + " ms"); } // 执行结果: // Integer 计算时长:51 ms // int 计算时长:6 ms
Ensuite, à travers les résultats d'exécution, on peut clairement découvrir que le boxing automatique de nouveaux objets fréquents et l'allocation de mémoire entraînent des pertes de performances dans le temps et dans l'espace.
Petit résumé
Grâce à la lecture du code source et à l'analyse des tests ci-dessus, nous pouvons conclure que lorsque nous calculons habituellement des statistiques ou saisissons des paramètres dans les méthodes, nous devrions faire de notre mieux pour éviter ce problème de conversion de type. Pour améliorer l’efficacité d’exécution de l’ensemble de notre code.
Unboxing (intValue)
Il n'y a pas de logique compliquée dans le unboxing et il renvoie directement le type de base de la valeur.
Supplément : la mise en boîte et le déballage automatiques se produisent-ils toujours ?
En fait, pas nécessairement. Regardez l'exemple de code ci-dessous. Les résultats de sortie ont été commentés après l'instruction de sortie.
public static void main(String[] args) { // TODO 自动生成的方法存根 Integer a = 1; Integer b = 2; Integer c = 3; Integer d = 3; Integer e = 321; Integer f = 321; Long g = 3L; System.out.println(c==d);//true //包装类的==在没有遇到算术运算的情况下不会自动拆箱 System.out.println(e==f);//false System.out.println(c==(a+b));//true System.out.println(c.equals(a+b));//true System.out.println(g==(a+b));//true //equals方法不会处理数据转型关系 System.out.println(g.equals(a+b));//false }
Les situations dans lesquelles le boxing et le unboxing automatiques se produisent sont les suivantes :
Autoboxing : Le type de base est attribué au type d'emballage. Par exemple : Entier i1 = 1;
Déballage automatique :
Le type d'emballage est attribué au type de base. Par exemple : int i2 = new Integer(1);
Comparez le type int avec le type Integer. Si les valeurs du type int et du type Integer sont égales, le résultat est toujours vrai.
Le type entier rencontre des opérations arithmétiques
Mais pourquoi dans l'exemple ci-dessus, les résultats de sortie de System.out.println(c==d); pas pareil Pareil ?
Principalement à cause de la méthode Integer.valueOf(). Une partie du code source d'Integer est publiée ci-dessous :
// private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
IntegerCache est la classe interne statique d'Integer et valueOf() est la méthode d'empaquetage. Comme le montre le code source, le cache est un tableau de cache. Lorsque le paramètre d'entrée i de la méthode valueOf() est compris dans la plage [-128,127], la valeur entière du tableau de cache sera renvoyée. Un entier sera créé.
C'est pourquoi les résultats de sortie de System.out.println(c==d); et System.out.println(e==f); c et d sont dans l'intervalle de cache, ils renvoient donc la même référence ; tandis que e et f ne sont pas dans l'intervalle de cache, ils renvoient un nouvel Integer, qui n'est plus la même référence.
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide de la racine carrée en Java. Nous discutons ici du fonctionnement de Square Root en Java avec un exemple et son implémentation de code respectivement.

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Guide du générateur de nombres aléatoires en Java. Nous discutons ici des fonctions en Java avec des exemples et de deux générateurs différents avec d'autres exemples.

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.
