preface

This content is the last article [Dynamic proxy trilogy: part 1] – dynamic proxy is how “pit dropped” my 4500 dollars supplement, further analysis of the article. It is recommended to combine the two edible, mellow and soft, mouth melt.

All right, enough bullshit, let’s go…

The body of the

2, Class file format

Why does it start with a 2? Because the last article was 1

I don’t know how you feel about this part. At the beginning of learning, I was at a loss how to start. When combined step by step with reflection, JVM memory model, and class loading mechanisms. And then you look back and you see that everything is clear.

The beginning of the content of this article, let us according to our demo in the class: RentHouseProcessorHandler to analyze this problem. If we use the hex editor (such as: Sublime does) open the RentHouseProcessorHandler. Class files:

To tell you the truth, this line of writing, at first I said no. Oh, god, why are you showing me this shit… In fact, if we calm down, as in high school when learning math, physics formula to treat it seriously. It’s nothing more than a bunch of symbols with artificial meanings.

Before we get ready to read the hexadecimal text, let’s look at the Java Virtual Machine Specification (Java SE 7) definition of a class file:


2.1. Standard structure of Class files

2.1.1 standard structure

The content above is actually very easy to understand, do not contradict them because it is not common English. Let’s try to translate them: 1. Magic number; 2. Second version number; 3. Major version Number; 4. Number of constant pools; 5. Constant pool; 6. Permission identification; 7, such; 8. Parent class; 9. Number of interfaces; 10. Interface; 11. Number of variables; 12. Variables; 13. Number of methods; 14. Method….

Isn’t there something there? Isn’t there something that a class should be? That’s right, the structure of the Class file is to fix the rules in the Class we write. At the beginning, I thought it was profound and did not dare to understand them. When I am complacent, summon up the courage to prepare for a good, only to find that it is too simple… Just a few rules, that’s all.

2.1.2 Structure of special attention: table

It’s just a few rules, but there’s always something special about the rules: cp_info, for example. In Understanding the Java Virtual Machine, the authors refer to types ending in _info as “tables.” Let’s use the same expression here. In plain English, it is a type that has multi-level relationships.

Cp_info represents the constant pool (constant pool: first it is not the same thing as the run-time constant pool in the method area. The constant pool here holds literal and symbolic references.


Symbolic reference:

Symbolic reference:

  • Globally qualified names of classes and interfaces
  • The name and descriptor of the field
  • The name and descriptor of the method

Here’s what symbolic references do, and we want to start with a question. When the CPU executes a program, it is actually looking for the memory address of the corresponding instruction. But our Class file is compiled first, but has not yet been loaded into memory by the JVM, so there is definitely no memory address. So our Class file needs some kind of token that the JVM gets from the constant pool when it loads content, and then maps it to a specific memory address.


There are 14 constants in the Java Virtual Machine Specification (Java SE 7), each of which is a “table,” and each of which uses a common tag to indicate which type of constant it is. The details are as follows:

Here’s a look at the constant pool: let’s skip the magic u4, this version of U2, the main version of U2. Just look at constant_pool_count. If we skip the corresponding contents, then our constant_pool_count corresponds to 20 in hexadecimal and 32 in decimal, which means there are 32 contents in the constant pool? No, because the designer left the 0th position vacant for another purpose. So our constant pool only has 31 contents.

We can verify this problem with the Javap command.

The next byte: 0a, which translates to 10 in decimal, corresponds to the CONSTANT_Methodref_info in our table, and the next four bytes. They represent indexes 3 and 20. What does this index mean? Note the red marks in the figure below:

I’m not going to go through each of these, because it’s a process. If you are interested, you can try to interpret it for yourself. A tool, JavaClassViewer, is recommended to easily view these contents:


After the constant pool is finished, we have our normal variable, method information. Here we need to understand a new concept: descriptors. It’s clear to us what a variable or method looks like in Java source code. But what do they look like in a class file? This is actually called a descriptor.

Above talk about dynamic proxy, we learned the ProxyGenerator. GenerateProxyClass (proxyName, interfaces, accessFlags); In the method, through:

dout.writeInt(0xCAFEBABE);
MethodInfo minfo = new MethodInfo("<init>"."(Ljava/lang/reflect/InvocationHandler;) V",ACC_PUBLIC);    
Copy the code

$Proxy0 = $xy0; $Proxy0 = $xy0; Let’s move on to descriptors.

2.2 descriptors of variables and methods

There’s no need to say what 0xCAFEBABE means. And

means constructor. Plus (Ljava/lang/reflect/InvocationHandler;) V and ACC_PUBLIC can be represented as public constructors of InvocationHandler, where V means no return value.

  • <init>: object constructor method.
  • <clinit>: class constructor method.

The content here is called method descriptors, so let’s take a quick look at some diagrams to deepen this aspect.

Both primitive types and void have an uppercase character in their descriptor; What about descriptors for reference types?

“L” + fully qualified name of type + “;”

For example: Ljava/lang/Object; That means this is an Object type.

The rules for method descriptors are simple, as summarized in the figure above:

(Parameter Type 1 Parameter Type 2 Parameter type 3…) Return value type

For example: int[] m(int I,String s) converts to descriptor: (ILjava/lang/String;) [I

I don’t know if we have a clear understanding of descriptors after so many graphs. Anyway we ProxyGenerator. GenerateProxyClass (proxyName, interfaces, accessFlags); What is written in is the descriptor of the concrete method.

The DataOutputStream is then converted to a byte array, so that’s what we fixed in our Class file. So our Class file is now built, and all we need to do is load it into memory for us to use.

2.3, ending

Here we are ready to wrap up the class file structure. I don’t know if you guys got anything. Because space is limited, some content can not be described clearly in two sentences. So I’m sorry to skip over some of the content. For details, see Understanding the Java Virtual Machine.

I hope you can understand.

I am a fresh graduate, recently maintained a public account with friends, the content is that we are in the transition from fresh graduate to the development of this way stepped on the pit, has been our step by step learning records, if interested in friends can pay attention to it, together with fuel ~