Detailed Explanation of Java Constant Pool

  • 2021-11-13 01:43:06
  • OfStack

Directory (1) class constant pool (2) running constant pool (3) Base type wrapper class constant pool (4) String constant pool summary

There are several different constant pools in java, and the following is an introduction to several constant pools in java, the most common of which is the string constant pool.

(1) class constant pool

In Java, the Java class will form an class file after being compiled; In addition to the description information of class version, field, method and interface, class file also contains a constant pool, which is used to store various literal and symbol references generated by compiler. Each class file has an class constant pool.

Among them, literal quantities include: 1. text string 2.8 basic types of values 3. constants declared as final, etc.;

Symbol references include: 1. The fully qualified names of classes and methods 2. The names and descriptors of fields 3. The names and descriptors of methods.

(2) Running constant measuring pool

The runtime constant pool exists in memory, which is the version of class constant pool after it is loaded into memory, and is part of the method area (JDK 1.8 runtime constant pool is in meta-space, which is also an implementation of the method area). The difference is that its literal value can be added dynamically (intern () of String class), and symbolic references can be resolved as direct references.

When JVM executes a class, it must go through loading, connection and initialization, and connection includes three stages: verification, preparation and parsing. When the class is loaded into memory, jvm will store the contents of class constant pool into the runtime constant pool. The constants mentioned here include: basic type wrapper class (wrapper class does not manage floating-point type, but shaping only manages-128 to 127) and string type (that is, String can be forced into the constant pool through String. intern () method). The runtime constant pool is private to each class. In the parsing phase, symbolic references are replaced with direct references.

(3) Constant pool of basic type packaging class

Most of the wrapper classes of the Java primitive type implement constant pool technology. The four wrapper classes Byte, Short, Integer and Long create corresponding types of cached data with values [-128, 127] by default, Character creates cached data with values in the range of [0, 127], Boolean directly returns True or False, and if it exceeds the corresponding range, new objects will be created. The wrapper classes Float and Double, two floating-point number types, do not implement constant pool technology.

Integer cache source code:


/**
* This method will always cache -128  To  127 (including endpoints) and can cache other values outside this range. 
*/
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
      return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];
}

Take chestnuts:


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));

Results:

i1=i2 true
i1=i2+i3 true
i1=i4 false
i4=i5 false
i4=i5+i6 true
40=i5+i6 true

Explanation: The result of the 1-4 statement should be obvious, because the 1 line of code Integer i1=40 will be boxed, which means that this line of code is equivalent to Integer i1=Integer. valueOf (40). The Integer. valueOf () method caches numbers between [-128, 127] based on the consideration of reducing the number of object creations and saving memory. If the object in the cache is returned directly within this number range. Beyond that, direct new comes out, apparently 40 in the constant pool's cache [-128, 127] range; Therefore, i1 directly uses objects in the constant pool. Integer i1 = new Integer (40) creates a new object directly; The statement i4 = = i5 + i6, because the + operator does not apply to Integer objects, first i5 and i6 perform automatic unpacking operations and add values, that is, i4 = = 40. Then the Integer object cannot be directly compared with the numeric value, so i4 automatically unboxes and changes to int value 40. Finally, this statement changes to 40 = = 40 for numeric comparison, so the result is true. The same is true for clause 6.

Extra note: All integer wrapper class objects are compared with each other using the equals method.

For Integer var =? For assignments between-128 and 127, Integer objects are generated in IntegerCache. cache, which will reuse existing objects. Integer values in this interval can be directly judged by = =, but all data outside this interval will be generated on the heap, and existing objects will not be reused. It is recommended to use equals method for judgment.

(4) String constant pool

In JDK 1.6 and before, the string constant pool was stored in the method area, and after JDK 1.7, the string constant pool was moved to the heap.

In HotSpot VM, a global table that records interned string is called StringTable, which is essentially an HashSet < String > ; There is only one StringTable per instance of HotSpot VM, which is shared by all classes.

Note: It only stores references to java. lang. String instances, not the contents of String objects

The string constant pool is somewhat different from the above basic type wrapper class constant pool. The string constant pool does not cache 1 data in advance, but returns a reference to the object if the string to be created exists in the constant pool, and if it does not exist, creates 1 and puts it in the constant pool;

In Java, there are two methods to create string objects, one is literal direct creation, and the other is new1 String objects. The process of creating string objects by these two methods will be different;


(1)String str = "abc";
(2)String str = new String("abc");

If the object is created in the first way, Because it is created literally, So it's certain at compile time, If the string is not in the constant pool, the string is placed in the constant pool and a reference to the string object is returned. If you return a reference to a string object directly in a constant pool, If the object is created in the second way, Because you want to create String type objects, String objects are loaded into the heap of memory at runtime, which belongs to runtime creation, so you should first create an String object in the heap, and then look for the same string in the constant pool. If so, you will return the reference of Sring objects in the heap, and if not, you will add the string to the constant pool.

Take chestnuts:

Compare the following two methods of creating strings:

String str1 = new String("abc");

String str2 = "abc";

Answer: The first is to create a new object with new (), which will be stored in the heap. A new object is created every time it is called. Run-time creation.

The second is to create an object reference variable str2 for String class in the stack, and then find out if there is "abc" in the string constant pool by symbol reference. If not, store "abc" in the string constant pool, and make str2 point to "abc". If there is already "abc", make str2 point to "abc" directly. "abc" is stored in the constant pool during compilation.

String s = new String("abc")
How many objects does this statement create?

Answer: Two in all. The first object is the "abc" string stored in the constant pool, and the second object is the String object in Java Heap. Don't confuse that s is the String object placed in the stack and pointing to the Heap heap.

String s1 = new String("s1") ;

String s1 = new String("s1") ;

How many objects have been created in the above 1?

Answer: 3, 1 in the compile-time constant pool and 2 in the run-time heap. (For new, 1 object is created on the heap for every new1, and for quotation marks, if it is already in the constant pool, it points directly to it. Do not create it.)

Summarize

This article is here, I hope to give you help, but also hope that you can pay more attention to this site more content!


Related articles: