Maison  >  Article  >  Java  >  machine virtuelle Java : pool de constantes d'exécution

machine virtuelle Java : pool de constantes d'exécution

巴扎黑
巴扎黑original
2017-06-26 09:56:061480parcourir

1. Introduction au pool de constantes d'exécution

Le pool de constantes d'exécution (Runtime Constant Pool) fait partie de la zone des méthodes. En plus de la version de la classe, des champs, des méthodes, des interfaces et d'autres descriptions dans le fichier Class, il y a aussi une information qui est le pool constant (Constant Pool Table), qui est utilisé pour stocker au moment de la compilation les divers littéraux et références de symboles générés, cette partie sera stockée dans le pool de constantes après le chargement de la classe.

Les constantes d'exécution sont relatives aux constantes. Elles ont une fonctionnalité importante : la dynamique. Bien entendu, les constantes dynamiques ayant la même valeur proviennent uniquement de sources différentes des constantes dont nous parlons habituellement, mais elles sont toutes stockées dans la même zone mémoire du pool. Le langage Java ne nécessite pas que les constantes soient générées uniquement lors de la compilation. De nouvelles constantes peuvent également être générées pendant l'exécution. Ces constantes sont placées dans le pool de constantes d'exécution. Les constantes mentionnées ici incluent : le type de base la classe wrapper (la classe wrapper ne gère pas les types à virgule flottante, l'entier ne gère que -128 à 127) et String (peut également être transmis String.intern()La méthode peut forcer la mise de String dans le pool de constantes)

2. Pool de constantes d'informations dans le fichier de classe

Dans la structure du fichier de classe, les 4 premiers octets sont utilisés pour stocker Numéro magique, utilisé pour déterminer si un fichier peut être accepté par la JVM, puis 4 octets sont utilisés pour stocker le numéro de version. Les 2 premiers octets stockent le numéro de version mineure, les 2 derniers octets stockent le numéro de version majeure, puis. sont utilisés pour stocker des constantes. Le nombre de constantes n'étant pas fixe, une donnée de type U2 (constant_pool_count) est placée à l'entrée du pool de constantes pour stocker la valeur du nombre de capacités constantes du pool.

Le pool de constantes est principalement utilisé pour stocker deux types de constantes : les littéraux et les références symboliques. Les littéraux sont équivalents au concept de constantes au niveau du langage Java, comme les chaînes de texte, déclarées comme valeurs constantes finales, etc. . La référence de symbole est un concept lié aux principes de compilation, comprenant les trois types de constantes suivants :

  • Noms complets de classes et d'interfaces

  • . Noms et descripteurs de champs

  • Noms et descripteurs de méthodes

3.Avantages du pool constant

Le pool constant est à éviter. création et destruction fréquentes d'objets qui affectent les performances du système et implémente le partage d'objets. Par exemple, le pool de constantes de chaîne place tous les littéraux de chaîne dans un pool de constantes pendant la phase de compilation.

  • Économisez de l'espace mémoire : toutes les constantes de chaîne identiques dans le pool de constantes sont fusionnées et n'occupent qu'un seul espace.

  • Gagnez du temps d'exécution : lors de la comparaison de chaînes, == est plus rapide que equals(). Pour deux variables de référence, utilisez simplement == pour déterminer si les références sont égales, et vous pouvez également déterminer si les valeurs réelles sont égales.

La signification du double signe égal ==

  • Le double signe égal est appliqué entre les types de données de base, et leur numérique les valeurs sont comparées.

  • Un double signe égal est appliqué entre les types de données composites (classes) pour comparer leurs adresses de stockage en mémoire.

4. Classes d'empaquetage de type de base et pools constants

La plupart des classes d'empaquetage de type de base en Java implémentent la technologie de pool constant, à savoir Byte, Short, Integer. ,Long,Caractère,Booléen. Ces cinq classes d'empaquetage créent des types correspondants de données de cache avec des valeurs [-128, 127] par défaut, mais de nouveaux objets seront toujours créés au-delà de cette plage. Les deux classes wrapper de type à virgule flottante Float et Double n'implémentent pas la technologie de pool constant .

1) Pool entier et constant

machine virtuelle Java : pool de constantes dexécution
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);

System.out.println("i1=i2   " + (i1 == i2));
System.out.println("i1=i2+i3   " + (i1 == i2 + i3));
System.out.println("i1=i4   " + (i1 == i4));
System.out.println("i4=i5   " + (i4 == i5));
System.out.println("i4=i5+i6   " + (i4 == i5 + i6));  
System.out.println("40=i5+i6   " + (40 == i5 + i6));


i1=i2   true
i1=i2+i3   true
i1=i4   false
i4=i5   false
i4=i5+i6   true
40=i5+i6   true
machine virtuelle Java : pool de constantes dexécution
Explication :
  • Integer i1=40 ; Java encapsulera directement le code dans Integer i1=Integer.valueOf(40); la piscine constante.

  • Integer i1 = new Integer(40); Dans ce cas, un nouvel objet sera créé.

  • Instruction i4 == i5 + i6, car l'opérateur + ne s'applique pas aux objets Integer, i5 et i6 effectuent d'abord des opérations de déballage automatique et ajoutent des valeurs , c'est-à-dire i4 == 40. Ensuite, l'objet Integer ne peut pas être directement comparé à la valeur numérique, donc i4 le déballe automatiquement et le convertit en valeur int 40. Enfin, cette instruction est convertie en 40 == 40 pour une comparaison numérique.

2) Chaîne et pool de constantes - affectation de méthode ordinaire

machine virtuelle Java : pool de constantes dexécution
String str1 = "abcd";
String str2 = new String("abcd");
System.out.println(str1==str2);//false

String str1 = "str";
String str2 = "ing";
String str3 = "str" + "ing";
String str4 = str1 + str2;
System.out.println("string" == "str" + "ing");// true
System.out.println(str3 == str4);//false

String str5 = "string";
System.out.println(str3 == str5);//true
machine virtuelle Java : pool de constantes dexécution
解释:
  • "abcd"是在常量池中拿对象,new String("abcd")是直接在堆内存空间创建一个新的对象。只要使用new方法,便需要创建新的对象

  • 连接表达式 +,只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入常量池中

  • 对于字符串变量的“+”连接表达式,它所产生的新对象都不会被加入字符串池中,其属于在运行时创建的字符串,具有独立的内存地址,所以不引用自同一String对象。

3)String与常量池-静态方法赋值

machine virtuelle Java : pool de constantes dexécution
public static final String A; // 常量A
public static final String B;    // 常量B
static {  
   A = "ab";  
   B = "cd";  
}  
public static void main(String[] args) {  
// 将两个常量用+连接对s进行初始化  
String s = A + B;  
String t = "abcd";  
if (s == t) {  
    System.out.println("s等于t,它们是同一个对象");  
  } else {  
    System.out.println("s不等于t,它们不是同一个对象");  
  }  
}
machine virtuelle Java : pool de constantes dexécution
解释:

s不等于t,它们不是同一个对象。A和B虽然被定义为常量,但是它们都没有马上被赋值。在运算出s的值之前,他们何时被赋值,以及被赋予什么样的值,都是个变数。因此A和B在被赋值之前,性质类似于一个变量。那么s就不能在编译期被确定,而只能在运行时被创建了。

4)String与常量池-intern方法

machine virtuelle Java : pool de constantes dexécution
public static void main(String[] args) {
  String s1 = new String("计算机");
  String s2 = s1.intern();
  String s3 = "计算机";
  System.out.println("s1 == s2? " + (s1 == s2));
  System.out.println("s3 == s2? " + (s3 == s2));
}
s1 == s2? false
s3 == s2? true
machine virtuelle Java : pool de constantes dexécution
解释:

String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,如果有则返回该字符串的引用,如果没有则添加自己的字符串进入常量池

5)String与常量池-延伸

String s1 = new String("xyz"); //创建了几个对象?
解释:

考虑类加载阶段和实际执行时。

  • 类加载对一个类只会进行一次。”xyz”在类加载时就已经创建并驻留了(如果该类被加载之前已经有”xyz”字符串被驻留过则不需要重复创建用于驻留的”xyz”实例)。驻留的字符串是放在全局共享的字符串常量池中的。

  • 在这段代码后续被运行的时候,”xyz”字面量对应的String实例已经固定了,不会再被重复创建。所以这段代码将常量池中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给s1 持有

这条语句创建了2个对象。

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!

Déclaration:
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