📜 ⬆️ ⬇️

Pool of constants

Many people know that every .class file has a wonderful data structure called a constant pool. But not every Java developer, looking at the source, can even approximately estimate how many constants will be created in the pool.

Take, for example, this code:

System.out.println("Hello World!"); 

It is translated into three bytecode instructions: getstatic (for loading the static field System.out), ldc (for loading the constant string “Hello World!”) And invokevirtual (for executing the virtual function println). Try to estimate how many constants are needed for this code to work.

It turns out that this string uses 14 constants, which can be schematically depicted as follows:

As we can see, most constants are references to other constants. Each constant has a type, a value, and a number by which it can be referenced. Here are the base types that don't refer to anything:

Here are some of the reference types:

To access a field, you need not only its name, but also the full name of the class where the field is declared, as well as the field type. To access a method, you need a class, a name, and a method signature. Fortunately, the entire signature is encoded into one line regardless of the number of method parameters: primitive types are encoded with one letter (for example, D = double), objects with the letter L, followed by the full class name and a semicolon, and one array level adds square bracket. In parentheses are the types of arguments, followed by the return type (V is void). For example, the signature (IDLjava/lang/Thread;)Ljava/lang/Object; will have this method:
 Object m(int i, double d, Thread t) {...} 

From the fact that to refer to the method requires its exact signature, developers sometimes attach to NoSuchMethodError. Let's say you changed the return type of a method to a more specific one. Then the calls of this method from other classes remain the same, and the compiler will not reassemble these classes, because the source files have not changed. However, if you try to call this method at runtime, the Java machine will look for the old signature.
')
If you automatically generate Java code, remember that the maximum constant number in the pool does not exceed 65535, after that there will be a compilation error. This is not such a large number, given the huge number of links and the fact that long and double occupy two positions. Knowing the pool device will help you control how it is filled when generating code.

More information about the device pool of constants can be found in §4.4 specification of the Java virtual machine.

Source: https://habr.com/ru/post/222519/


All Articles