- The Java Class File Constant Pool
- Table of contents
- Structure Of the Constant Pool
- Types Of Constant Pool Entries
- CONSTANT_Utf8
- CONSTANT_Integer, CONSTANT_Float
- CONSTANT_Long, CONSTANT_Double
- CONSTANT_Class
- CONSTANT_String
- CONSTANT_Fieldref
- CONSTANT_Methodref
- CONSTANT_InterfaceMethodref
- CONSTANT_NameAndType
- CONSTANT_MethodHandle
- CONSTANT_MethodType
- CONSTANT_InvokeDynamic
- Analyze the Class Using the Constant Pool
- Author: Thomas Lemmé
- 2 thoughts on “The Java Class File Constant Pool”
- Leave a Reply Cancel reply
- Recent Posts
- Pages
- Recent Comments
- Archives
- Categories
- Properties file vs constants class in java
- Properties file vs Constants class in Java
- Spring and Constants class from property file
- What is the best way to store common strings (properties file / constants class) in Java Spring boot Project?
- Spring Boot — Read custom properties file using Constants class
The Java Class File Constant Pool
Everything that is constant in a class file is reflected in the constant pool. This means not only string or numeric constants, but everything that does not change during runtime, e.g.: variable and method names, method signatures, class names etc.
The information contained in the constant pool can be used to better understand the Java compiler or to do some static analysis.
In the fourth part of the series about the Java Class File Format I take a look at the constant pool.
Table of contents
Structure Of the Constant Pool
u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1];
Since the constant pool is of variable size, the first two bytes (u2) denote the count of constant pool entries. In fact it is the count minus one, because the first index (0) is always left empty. That means I f the count was e.g. 4, there would be entries with indices 0, 1, 2, 3 but 0 would be empty. This is a little bit strange and I’m not sure if this makes sense in any way.
After the count bytes all the entries follow, each starting with a first byte denoting the type of the entry called tag.
Below is a list of the tag values from the JVM spec.
Constant Type | Value |
---|---|
CONSTANT_Class | 7 |
CONSTANT_Fieldref | 9 |
CONSTANT_Methodref | 10 |
CONSTANT_InterfaceMethodref | 11 |
CONSTANT_String | 8 |
CONSTANT_Integer | 3 |
CONSTANT_Float | 4 |
CONSTANT_Long | 5 |
CONSTANT_Double | 6 |
CONSTANT_NameAndType | 12 |
CONSTANT_Utf8 | 1 |
CONSTANT_MethodHandle | 15 |
CONSTANT_MethodType | 16 |
CONSTANT_InvokeDynamic | 18 |
Types Of Constant Pool Entries
There are 14 different types of Constant Pool entries. Some of them are self-contained, some of them point to other constants, and one type points to the attributes table, wich we will handle later in this series of blog posts.
CONSTANT_Utf8
The UTF-8 constant has a length and an array of bytes which contains an UTF-8 encoded string constant. This may be a string literal such as “Hello, World” but also everything else which is represented as a string such as variable, class, filed and method names, method signatures etc.
CONSTANT_Integer, CONSTANT_Float
The integer & float constants contain a 32-bit representation of an integer or float value. It is important to know, that all other numeric types smaller than integer such as short, byte and also boolean, are handled as integer values in the java byte code.
public static final boolean CONSTANT_BOOL = false;
leads to an integer constant pool entry with value 0.
CONSTANT_Long, CONSTANT_Double
The long & double constants contain a 64-bit (2 x 32-bit) representation of an long or float double.
Each constant of this types takes two indices in the constant pool. That means it creates a constant at a specific index and the following index is empty. This was a design decision even the creators of the Java Class File Format regret. From the spec:
In retrospect, making 8-byte constants take two constant pool entries was a poor choice.
CONSTANT_Class
The class constant entry contains the index of an UTF-8 constant entry holding a fully qualified class name such as java/lang/Object. This type of entry itself may be referenced e.g. by a MethodRef constant.
CONSTANT_String
The String constant entry is used for constant java.lang.String entries such as string literals. It does not hold the string itself but references to an UTF-8 constant entry.
CONSTANT_Fieldref
The Fieldref constant is used for non-constant ( static final ) fields. It references a Class and NameAndType constant.
CONSTANT_Methodref
This constant is used when invoking a method via invokevirtual, invokespecial, invokestatic
CONSTANT_InterfaceMethodref
This constant is used when invoking a method via invokespecial, invokestatic, invokeinterface
CONSTANT_NameAndType
The NameAndType constant is used for methods and fields, containing tow references to UTF-8 constants containing their names and signatures.
CONSTANT_MethodHandle
A MethodHandle consists of a kind and a reference to an item of the Constant Pool. The type of the referenced Constant Pool item depends on the kind of method handle.
CONSTANT_MethodType
The MethodType describes the signature of a MethodHandle constant.
CONSTANT_InvokeDynamic
The InvokeDynamic constant is used by the invokedynamic bytecode instruction to specify a bootstrap method.
Analyze the Class Using the Constant Pool
So what do the entries of the Constant Pool tell us?
At one hand we can learn some things about the Java compiler. For Example, that it optimizes string concatenation by replacing it with a StringBuilder . So we can find a java/lang/StringBuilder class entry in the Constant Pool although we have not even used this class explicitly.
Another optimization we can see in the constant pool is concatenation of string literals or constants at compile time.
final String TABLE = "person"; String query = "SELECT * " + "FROM " + TABLE + " p ";
Instead of creating three UTF-8 constants, the java compiler creates one UTF-8 constant for the TABLE constant and one concatenated entry containing «SELECT * FROM person p » .
At the other hand we can already do some static analysis of the class we were reading. We can filter the for all MethodRef and InterfaceMethodRef constants to see which methods have been called or filter all Class constants to see all classes related to the class.
So although we cannot say anything about the type hierarchy (that means which classes or interfaces our class extends or implements), we can see a kind of “network” of the types our class depends on.
Author: Thomas Lemmé
I am a Java Developer currently working at one of the top APM vendors as a Java agent developer. View all posts by Thomas Lemmé
Author Thomas Lemmé Posted on 11.10.2017 04.12.2018 Categories ClassFileReader Tags class, constant-pool, java, jvm
2 thoughts on “The Java Class File Constant Pool”
Hello, it’s seems interesting how Java can handle OOP with the class inded. Can I share this article to my friend?
Leave a Reply Cancel reply
Recent Posts
Pages
Recent Comments
Archives
Categories
Properties file vs constants class in java
Solution: Add file to the folder and then add below annotation to above your class that want to use properties and then use annotation like below: For example , if you distribute your application to end users to install on their machines and it has constants that you do not want users to change it would be a bad idea to put them in a properties file.
Properties file vs Constants class in Java
Use hardwired constants in your Java code when you don’t want users / deployers / testers / tests changing them.
Use a properties file when you do want this to be a possibility.
The point is that changing a hard-wired constant in your application’s source code entails editing the source code, rebuilding and redeploying. By contrast, changing a properties file may be as simple as firing up NotePad.
As you said that changing properties file is simple whereas changing constants file requires us to rebuild the application. So, shouldn’t we always prefer to use properties file?
No. Not always. For example , if you distribute your application to end users to install on their machines and it has constants that you do not want users to change it would be a bad idea to put them in a properties file.
It is impossible to reduce this to «always prefer X» recommendation. You need to understand your own application requirements and decide for yourself.
Property file:
Is it configurable per environemnt etc.
Applicable to particular situation (list of states for rules etc). key-value pairs. Can be modified by someone other than developer ie, analysts, business users etc.
Are constants. Not configurable. Mostly for optimization and reuse. To avoid keys being scattered.
For constants like YES = «yes». Not really a key value. Keys for cache etc.
Constants to ensure that retrieval and set use the same key even though from different places in the application, EXAMPLE xyz.put(KeyConstants.SOME_KEY, «somevalue»); xyz.get(KeyConstants.SOME_KEY) from different classes, ofcouse xyz being shared or singleton.
- Constants — when you don’t mind re-compiling the application each time you change value. Sort of an irony here. Why would you change something if it has been called a constant 🙂
- Properties file — when you want the luxury of just changing the value and maybe restarting the application to pick up the change.
Properties file vs Constants class in Java, These aspects make properties file really useful for storing configurations. On the other hand, constants classes need to be compiled, but are «safer» if you plan not to change those constants very often. Constants are fixed in compile time. So if you don’t foresee any changes of values Constants will be …
Spring and Constants class from property file
After a bit of testing, this is the issue:
System.out.println(Constants.class.getClass());
This prints java.lang.Class which may not have been loaded by the classloader. This is because the class of a SomeClass.class is java.lang.class .
Remove the getClass() and the Classloader won’t be null. No need for the clazz variable. This should be all you need to do:
ClassLoader cl = Constants.class.getClassLoader();
Configuration — Constants and properties in java, I found a better solution to homogenize the code and has everything as constants. With the same Configurations class and .properties file: Since getInstance() method is static it is possible to init the constants in the class Constants. A class to store the name to the property in .properties file: public …
What is the best way to store common strings (properties file / constants class) in Java Spring boot Project?
Generally all constants/string values which are fixed will go under util package as Constants.java or Constants.java and from there you can have static import wherever you want to use it.
Constants vs properties in java, Declaring them in a class would warrant re-building the App again and again but if these constant don’t change or are not required to be accessed by multiple parties, you can very easily pick the static final class approach. Android declares constants dynamically generated in R.java file as an example.
Spring Boot — Read custom properties file using Constants class
Add AppProps.properties file to the resources folder and then add below annotation to above your class that want to use properties
@PropertySource("classpath:AppProps.properties")
and then use Value annotation like below:
@Value("$") private String requestSuccess;
Java — Spring and Constants class from property file, Sorted by: 1. After a bit of testing, this is the issue: System.out.println (Constants.class.getClass ()); This prints java.lang.Class which may not have been loaded by the classloader. This is because the class of a SomeClass.class is java.lang.class. Remove the getClass () and the Classloader …