1. Introduction
Que sont l'auto-boxing et l'auto-unboxing ? Qu’est-ce que le cache entier ? Quelle est la relation entre eux ?
Regardons d’abord une question.
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a==b);
Integer c = 1;
Integer d = 1;
System.out.println(c==d);
Integer e = 128;
Integer f = 128;
System.out.println(e==f);
Répondez d'abord, regardez la réponse plus tard.
La réponse est faux vrai faux, avez-vous raison ?
Maintenant qu'un élément est apparu, listons ensemble les points de connaissances
2. Classe d'emballage
Il existe huit types de données de base en Java, qui peuvent être divisés en trois catégories :
Les classes d'emballage regroupent huit types de données de base dans des classes afin qu'elles puissent utiliser les trois fonctionnalités principales de Java : l'encapsulation, l'héritage et le polymorphisme. La relation correspondante est la suivante :
Type de données de base |
Classe d'emballage correspondante |
byte |
Byte |
short |
Short |
int |
Entier |
long | Caractère |
Les six classes d'empaquetage correspondant aux types numériques héritent toutes de la classe Number. |
3. Boxing automatique et déballage automatique |
Huit types de données de base correspondent à huit classes d'emballage, alors comment effectuent-ils la conversion des données ? //基本数据类型转包装类
//1.有参构造
Integer a = new Integer(1);
//2.实际上,有参构造的参数也可以是字符串,不过要使用正确的数据,“123abc”不可能会转换为Integer类型
Integer b = new Integer("123");
//3.valueOf()
Integer c = Integer.valueOf(123);
//包装类转基本数据类型(xxxValue() float是floatValue() double是doubleValue())
int d = a.intValue();
Les formes ci-dessus sont relativement cohérentes avec la cognition. Pour obtenir un objet, vous pouvez utiliser new ou appeler une certaine méthode. Pour obtenir une valeur, appelez un certain attribut de l'objet. |
Après Java 5.0, vous n'avez plus besoin d'être aussi gênant. De nouvelles fonctionnalités de boxe automatique et de déballage automatique ont été ajoutées. En fait, les deux concepts sont très faciles à comprendre. | int a = 10;
Integer b = a; //自动装箱
int c = b; //自动拆箱
À première vue, la forme objet = valeur numérique n'est pas conforme à la cognition, mais elle peut être obtenue à l'aide de la boxe automatique et du déballage automatique. En fait, le compilateur l'implémente toujours à l'aide de valueOf() et xxxValue().
Jetons un coup d'œil au code source de valueOf(). | /**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
valueOf() ne renvoie pas simplement un objet Integer, mais fait d'abord un jugement si les données d'entrée correspondent à une certaine plage, un objet spécifique sera renvoyé à partir des commentaires, cette plage est par défaut [- 128,127], et. peut être une plage plus grande ; au-delà de cette plage, de nouveaux objets seront renvoyés. Les données IntegerCache utilisées sont le cache d'Integer. |
4. Cache Interger
Les calculs numériques sont fréquemment utilisés dans la vie quotidienne. Si vous continuez à recevoir de nouveaux objets Integer, la surcharge sera donc très importante, Java générera automatiquement un tableau statique comme cache lors de l'exécution du programme. y correspond par défaut. La plage du tableau de cache est [-128,127]. Tant que les données se trouvent dans cette plage, l'objet correspondant peut être obtenu à partir du cache. |
Regardez le code source d'IntegerCache. | /**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
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() {}
}
Vous pouvez voir qu'IntegerCache est une classe interne statique d'IntegerCache.cache appelée par valueOf() est un objet tableau. La taille du tableau dépend des valeurs maximales et minimales de la plage. [-128, 127] , bien sûr (le commentaire dit) cette plage peut également être modifiée via la JVM (je ne comprends pas cela). Ensuite, chaque élément du tableau se verra attribuer un objet Integer et le cache sera formé.
Il existe un cache de tableau, ce qui signifie que si la valeur est dans [-128,127], l'objet Integer créé à l'aide de valueOf() ou de la boxe automatique est retiré du tableau, donc l'adresse mémoire pointée par l'objet est exactement le même. Si vous utilisez new ou dépassez cette plage, l'objet doit être recréé.
Bien sûr, non seulement Integer dispose d'un mécanisme de mise en cache, mais Byte, Short, Long et Character ont tous des mécanismes de mise en cache. La plage de Byte, Short, Integer et Long est comprise entre -128 et 127, et la plage pour Character est comprise entre 0 et 127.
5. Répondez à la question
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a==b);
Integer c = 1;
Integer d = 1;
System.out.println(c==d);
Integer e = 128;
Integer f = 128;
System.out.println(e==f);
1 Même si les deux objets créés par new ont la même valeur, ils pointent vers des adresses mémoire différentes. L'utilisation de == renvoie le résultat comme faux
2. mécanisme, Les deux objets sont en fait les mêmes et le résultat renvoyé est vrai
3 S'il dépasse la plage du cache, un nouvel objet sera créé lors de l'exécution. Si les deux objets sont différents, le résultat renvoyé est faux
.
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!