Références aux objets entiers en Java
Il n'y a pas de pointeur en Java, mais il y a aussi des concepts de référence. Ce dont nous voulons parler ici, c'est si Integer est le même objet.
1. Regardons d'abord un morceau de code:
public static void main (String [] args) {entier a1 = 100; Entier b1 = a1; // l'autre peut également être B1 = 100 champ de champ = null; try {field = a1.getClass (). GetDeclaredField ("Value"); } Catch (NosuchFieldException e) {// TODO Génératif Auto-Generated Block E.PrintStackTrace (); } Catch (SecurityException E) {// TODO Block de catch généré automatiquement e.printStackTrace (); } field.setAccessible (true); essayez {field.set (a1, 5000); } Catch (illégalArgumentException e) {// Bloc de capture généré par Auto-généré e.PrintStackTrace (); } Catch (illégalaccessException e) {// Bloc de capture généré par Auto-généré e.PrintStackTrace (); } System.out.println ("b1 =" + b1); Entier C1 = 100; System.out.println ("C1 =" + C1); } résultat:
B1 = 5000
C1 = 5000
D'après ce qui précède, tout d'abord, je veux expliquer quelques choses ici.
1) Pour entier, l'entier entre -128-127 a été initialisé et placé dans IntegerCache. S'il est emballé, l'objet lui sera retiré.
2) B1 = A1 est-il une affectation numérique ou le même objet? Cela peut être vu à partir des résultats que B1 et A1 pointent vers le même objet, pas la même valeur numérique
3) C1 = 100 signifie que pour les valeurs entre -128-127, tous les objets obtenus à partir d'IntegerCache. Une fois l'objet entier correspondant à 100, l'emballage ultérieur de 100 sera modifié. Parce que lors de l'obtention d'objets dans le cache, l'index du tableau est utilisé, et non des comparaisons numériques sont utilisées.
Cependant, modifier ce cache sera plus dangereux, donc cela ne vous dérange pas. Qui sait quel package ou plate-forme JAR pour emballer un 100 yuan, mais le résultat n'est pas 100 yuans, et il se bloquera à ce moment-là.
2. Grâce à la description ci-dessus, quelle est la réponse si elle est modifiée à cela
public static void main (String [] args) {entier a1 = 200; Entier b1 = a1; Champ de champ = null; try {field = a1.getClass (). GetDeclaredField ("Value"); } Catch (NosuchFieldException e) {// TODO Génératif Auto-Generated Block E.PrintStackTrace (); } Catch (SecurityException E) {// TODO Block de catch généré automatiquement e.printStackTrace (); } field.setAccessible (true); essayez {field.set (a1, 5000); } Catch (illégalArgumentException e) {// Bloc de capture généré par Auto-généré e.PrintStackTrace (); } Catch (illégalaccessException e) {// Bloc de capture généré par Auto-généré e.PrintStackTrace (); } System.out.println ("b1 =" + b1); Entier C1 = 200; System.out.println ("C1 =" + C1); } 3. Puis changez-le
public static void main (String [] args) {entier a1 = new Integer (100); Entier b1 = a1; Champ de champ = null; try {field = a1.getClass (). GetDeclaredField ("Value"); } Catch (NosuchFieldException e) {// TODO Génératif Auto-Generated Block E.PrintStackTrace (); } Catch (SecurityException E) {// TODO Block de catch généré automatiquement e.printStackTrace (); } field.setAccessible (true); essayez {field.set (a1, 5000); } Catch (illégalArgumentException e) {// Bloc de capture généré par Auto-généré e.PrintStackTrace (); } Catch (illégalaccessException e) {// Bloc de capture généré par Auto-généré e.PrintStackTrace (); } System.out.println ("b1 =" + b1); Entier C1 = 100; System.out.println ("C1 =" + C1); } Quelle est la réponse? Pour les nouvelles opérations, les objets ne sont pas encadrés, mais sont générés dans le tas.
Il n'est pas difficile de comprendre si vous comprenez la boxe, la mise en cache et la citation. Vous pouvez l'essayer vous-même.
Prenons d'abord quelques connaissances de base
Correspondance des types de base et des classes d'emballage octet octet Breft court int entier long long flotteur float double double char personnage booléen booléen
La correspondance entre les types de données de base dans les huit ci-dessus n'est que int-> entier char-> caractères. Les deux changements sont importants et les autres convertissent simplement la première lettre en minuscules.
Apprenons les nouvelles fonctionnalités de JDK5: emballage automatique et déballage
Boxe automatique: convertir les types de base en types de cours d'emballage
Déblocage automatique: Convertir le type de classe Wrapper en type de base
classe publique Demo_Integer {public static void main (String [] args) {// avant JDK1.5 int a = 100; Entier a1 = nouvel entier (a); // Enveloppez le type de données de base dans un objet, Box int b = a1.intValue (); // convertit l'objet en type de données de base et unbox // après JDK1.5 int x = 100; Entier x1 = x; // boîte automatiquement, convertissez le type de données de base en un objet int y = x1 + x; // Débranchez automatiquement, convertissez l'objet en type de données de base}}Choses à noter
classe publique Demo_Integer {public static void main (String [] args) {Integer a = null; int b = a + 100; // La couche inférieure du déballage automatique appellera A.IntValue (), A est null, et a lancera naturellement nullpointerException System.out.println (b); }}Questions d'entrevue
classe publique Demo_Integer {public static void main (String [] args) {Integer i1 = new Integer (97); Entier i2 = nouvel entier (97); System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("-------------"); Integer I3 = New Integer (197); INTEGER I4 = New Integer (197); System.out.println (i3 == i4); System.out.println (i3.Equals (i4)); System.out.println ("----------------"); }}Sortie: Faux True ----------------------------------
raison:
Nouveau consiste à ouvrir l'espace dans la mémoire du tas, et la valeur d'adresse de comparaison naturelle (==) est fausse.
Étant donné qu'Integer réécrit la méthode égale, la sortie égale est vraie.
Vous pouvez sentir qu'il est trop simple et n'a pas de contenu technique, car ce qui précède n'est pas le point, regardez le code ci-dessous
classe publique Demo_Integer {public static void main (String [] args) {Integer i1 = 127; Entier I2 = 127; System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("--------------"); Entier i3 = 128; Entier i4 = 128; System.out.println (i3 == i4); System.out.println (i3.Equals (i4)); System.out.println ("---------------"); }}Sortie: vrai vrai ------------------------------------------
raison:
Pourquoi deux objets lorsque INT est supérieur à 127? Le numéro 127 semble-t-il très familier?
-128 à 127 sont la plage de valeur de l'octet. S'il se trouve dans cette plage de valeur, la boxe automatique ne créera pas un nouvel objet et obtiendra-la à partir du pool constant
Si la plage de valeur de l'octet est dépassée, un nouvel objet sera créé.
Emballez automatiquement la couche sous-jacente et appelez la méthode de valeur de (), analyse de code source simple (JDK1.8):
Classe finale publique Integer étend le nombre de nombres implémentés comparables <Integer> {Valeur entière statique publique (int i) {// Lorsque i> = -128 et i <= 127, l'objet dans le tampon sera directement récupéré if (i> = IntegerCache.low && i <= IntegerCache.Low) Retour IntegerCache.Cache [i + (-ingerc.Low); return nouvel entier (i); // Si la plage de valeur d'octet dépasse la plage, elle sera créée dans la mémoire de tas} // La classe intérieure agit comme un tampon de classe statique IntegerCache {static final int low = -128; statique final int high; Cache entier final statique []; statique {// La valeur élevée peut être configurée par la propriété int h = 127; String IntegerCacheHighPropValue = Sun.Misc.vm.GetsAvedProperty ("Java.lang.integer.integerCache.high"); if (IntegerCacheHighPropValue! = null) {try {int i = paSeInt (IntegerCacheHighPropValue); i = math.max (i, 127); // La taille maximale du tableau est Integer.max_value h = math.min (i, Integer.max_value - (-low) -1); } catch (NumberFormatexception nfe) {// Si la propriété ne peut pas être analysée dans un int, ignorez-la. }} high = h; cache = nouvel entier [(élevé - bas) + 1]; int j = bas; pour (int k = 0; k <cache.length; k ++) cache [k] = nouveau entier (j ++); // La plage [-128, 127] doit être internalisée (JLS7 5.1.7) ASSERT IntegerCache.high> = 127; } private IntegerCache () {}}} 8 types de base de classes d'emballage et de pools d'objets
La plupart des types de base de classes d'emballage en Java mettent en œuvre une technologie de mise en commun constante. Ces classes sont des octets, courts, entiers, longs, caractère, booléens et les deux autres types de classes de wrapper avec numéro de point flottant ne sont pas implémentés. De plus, les cinq classes de wrapper en entier d'octets, courtes, entières, longues, le caractère ne peuvent utiliser le pool d'objets que lorsque la valeur correspondante est inférieure ou égale à 127, c'est-à-dire que l'objet n'est pas responsable de la création et de la gestion d'objets de ces classes supérieures à 127.
Connaissances prolongées
Dans la spécification JVM, chaque type a son propre pool constant. Un pool constant est une collection ordonnée de constantes utilisées par un certain type, y compris des constantes directes (types primitifs, chaînes) et des références symboliques à d'autres types, champs et méthodes. La raison pour laquelle il s'agit de référence symbolique plutôt que de spécifier directement d'autres types au moment de la compilation est que Java est lié dynamiquement, et ce n'est qu'à l'exécution que les instances de dépendance spécifiques du type sont déterminées en fonction de certaines règles. C'est la base de Java pour mettre en œuvre le polymorphisme.
Dans le JVM, tout le cycle de vie d'une classe commence à être chargé dans la mémoire de la machine virtuelle et jusqu'à ce qu'il soit déchargé hors de la mémoire. Tout son cycle de vie comprend: le chargement, la vérification, la préparation, l'analyse, l'initialisation, l'utilisation et le déchargement. L'étape d'analyse est le processus de la machine virtuelle remplacer les références de symbole dans le pool constant avec des références directes.
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.