Heim  >  Artikel  >  Java  >  Java Virtual Machine: Laufzeitkonstantenpool

Java Virtual Machine: Laufzeitkonstantenpool

巴扎黑
巴扎黑Original
2017-06-26 09:56:061399Durchsuche

1. Einführung in den Laufzeitkonstantenpool

Der Laufzeitkonstantenpool (Runtime Constant Pool) ist Teil des Methodenbereichs. Zusätzlich zur Klassenversion, Feldern, Methoden, Schnittstellen und anderen Beschreibungen in der Klasse-Datei gibt es auch eine -Information, nämlich den Konstantenpool (Constant Pool Table). Dies wird zum Speichern der zur Kompilierungszeit verwendeten verschiedenen Literale und Symbolreferenzen verwendet. Dieser Teil wird im Konstantenpool gespeichert, nachdem die Klasse geladen wurde.

Laufzeitkonstanten sind relativ zu Konstanten. Sie haben ein wichtiges Merkmal: Dynamik. Natürlich stammen dynamische Konstanten mit demselben Wert nur aus anderen Quellen als die Konstanten, über die wir normalerweise sprechen, aber sie werden alle im selben Speicherbereich im Pool gespeichert. Die Java-Sprache erfordert nicht, dass Konstanten nur während der Kompilierung generiert werden. Neue Konstanten können auch während der Laufzeit generiert werden. Diese Konstanten werden im Laufzeitkonstantenpool platziert. Zu den hier genannten Konstanten gehören: Basistyp Wrapper-Klasse (die Wrapper-Klasse verwaltet keine Gleitkommatypen, Ganzzahl verwaltet nur -128 bis 127) und String (kann auch String.intern()Die Methode kann erzwingen, dass String in den Konstantenpool eingefügt wird)2. Informationskonstantenpool in der Klassendatei

In der Klassendateistruktur werden die ersten 4 Bytes zum Speichern verwendet Magic Number wird verwendet, um zu bestimmen, ob eine Datei von der JVM akzeptiert werden kann. Anschließend werden 4 Bytes zum Speichern der Versionsnummer verwendet. Die ersten 2 Bytes speichern die Nebenversionsnummer, die letzten 2 Bytes speichern die Hauptversionsnummer und dann werden zum Speichern von Konstanten verwendet. Da die Anzahl der Konstanten nicht festgelegt ist, werden Daten vom Typ U2 (constant_pool_count) am Eingang des Konstantenpools platziert, um den Wert der Konstantenpoolkapazität zu speichern.

Der Konstantenpool wird hauptsächlich zum Speichern von zwei Arten von Konstanten verwendet: Literale und symbolische Referenzen entsprechen dem Konzept von Konstanten auf Java-Sprachebene, z. B. Textzeichenfolgen, die als endgültige Konstantenwerte usw. deklariert werden . Symbolreferenz ist ein Konzept im Zusammenhang mit Kompilierungsprinzipien, einschließlich der folgenden drei Arten von Konstanten:

    Vollständig qualifizierte Namen von Klassen und Schnittstellen
  • Feldnamen und Deskriptoren
  • Methodennamen und Deskriptoren
  • 3. Vorteile des Konstantenpools

Der Konstantenpool wird verwendet Vermeiden Sie die häufige Erstellung und Zerstörung von Objekten, die sich auf die Systemleistung auswirken, und implementieren Sie die gemeinsame Nutzung von Objekten. Beispielsweise legt der String-Konstantenpool während der Kompilierungsphase alle String-Literale in einem Konstantenpool ab.

    Speicherplatz sparen: Alle identischen String-Konstanten im Konstantenpool werden zusammengeführt und belegen nur einen Platz.
  • Laufzeit sparen: Beim Vergleich von Strings ist == schneller als equal(). Verwenden Sie für zwei Referenzvariablen einfach ==, um festzustellen, ob die Referenzen gleich sind, und Sie können auch feststellen, ob die tatsächlichen Werte gleich sind.
Die Bedeutung des doppelten Gleichheitszeichens ==

    Das doppelte Gleichheitszeichen wird zwischen grundlegenden Datentypen und ihren numerischen Typen angewendet Werte werden verglichen.
  • Ein doppeltes Gleichheitszeichen wird zwischen zusammengesetzten Datentypen (Klassen) angewendet, um ihre Speicheradressen im Speicher zu vergleichen.
4. Grundlegende Typverpackungsklassen und Konstantenpools

Die meisten grundlegenden Typverpackungsklassen in Java implementieren die Konstantenpooltechnologie, nämlich Byte, Short, Integer ,Long,Character,Boolean. Diese fünf Verpackungsklassen erstellen standardmäßig entsprechende Cache-Datentypen mit Werten ​​[-128, 127], es werden jedoch weiterhin neue Objekte außerhalb dieses Bereichs erstellt. Die beiden Wrapper-Klassen vom Typ Gleitkomma

Float und Double implementieren keine konstante Pooltechnologie

. 1) Ganzzahl- und Konstantenpool

Java Virtual Machine: Laufzeitkonstantenpool
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
Java Virtual Machine: Laufzeitkonstantenpool
Erklärung:
    Integer i1=40; Java kapselt den Code beim Kompilieren direkt in Integer i1=Integer.valueOf(40); der konstante Pool.
  • Integer i1 = new Integer(40); In diesem Fall wird ein neues Objekt erstellt.
  • Anweisung
  • i4 == i5 + i6, da der +-Operator nicht auf Integer-Objekte anwendbar ist, führen i5 und i6 zunächst automatische Unboxing-Vorgänge durch und fügen Werte hinzu

    , also i4 == 40. Dann kann das Integer-Objekt nicht direkt mit dem numerischen Wert verglichen werden, daher entpackt i4 es automatisch und konvertiert es in den int-Wert 40. Schließlich wird diese Anweisung für den numerischen Vergleich in 40 == 40 konvertiert.

  • 2) String und Konstantenpool – gewöhnliche Methodenzuweisung

Java Virtual Machine: Laufzeitkonstantenpool
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
Java Virtual Machine: Laufzeitkonstantenpool
解释:
  • "abcd"是在常量池中拿对象,new String("abcd")是直接在堆内存空间创建一个新的对象。只要使用new方法,便需要创建新的对象

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

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

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

Java Virtual Machine: Laufzeitkonstantenpool
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,它们不是同一个对象");  
  }  
}
Java Virtual Machine: Laufzeitkonstantenpool
解释:

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

4)String与常量池-intern方法

Java Virtual Machine: Laufzeitkonstantenpool
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
Java Virtual Machine: Laufzeitkonstantenpool
解释:

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

5)String与常量池-延伸

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

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

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

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

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

Das obige ist der detaillierte Inhalt vonJava Virtual Machine: Laufzeitkonstantenpool. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn