[JVM Story] The Birth of a Java Byte Code File

Long text in thousands of words, completely fictitious.

 

(1)

 


An intern came to the group. After Li Dafang finished, he felt his level was average, but he still stayed. Why?Let's guess.

Li Da-fat also enlightened himself in his heart. Students should not ask too much, as long as they are willing to go up and slowly.Just call it Xiao Bai.

Xiao Bai comes early every day, walks late, studies hard, and consults others from time to time.It just looks like a bit of a bad talent.

It's almost a week before you can write some "simple" code, a comment, an interface, a class.

public @interface Health {

    String name() default "";
}


public interface Fruit {

    String getName();

    void setName(String name);

    int getColor();

    void setColor(int color);
}


@Health(name = "Healthy fruit")
public class Apple implements Fruit {

    private String name;
    private int color;
    private double weight = 0.5;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getColor() {
        return color;
    }

    @Override
    public void setColor(int color) {
        this.color = color;
    }

    public double weight() {
        return weight;
    }

    public void weight(double weight) {
        this.weight = weight;
    }
}


Compared with the people around him, Xiao Bai's progress is slow. Maybe he is not smart enough, maybe he is not suitable for this. Xiao Bai seems to be a bit shaken.

These days, Xiao Bai obviously didn't come in as much as he did at the beginning. He seemed to want to give up. No, he fell asleep lying on the table.

 

(2)

 


In his dream, Xiao Bai comes to a strange and slightly gloomy place where there is an old house in front of him, refracting several beams of light from the incomplete cracks in the door.

Xiao Bai was a little afraid, but calmed down, took a few deep breaths and headed straight for the small house.

Xiao Bai pushed open the door and there was no one in the room.There is only one "machine" that "eats" at the table and "pulls" something out from behind from time to time.

Curious, Xiao Bai went up and prepared to examine carefully.

"What are you doing? Don't interfere with my work."Suddenly a sentence came out, frightened Xiao Bai a lot, and went back three steps in a hurry. Mom, my heart was jumping out.

"Who are you?"And said something in panic.

"I'm a compiler." Oh, the machine used to talk, so Xiao Bai slowed down.

"Compiler", Xiao Bai seems to have heard about it, but he can't remember it for a moment, so he guessed it.

"Are you the Xiaobian in the comments on the Internet?"

"You're the one," the compiler said with a blank look.

The compiler thought he would have driven you away if it had not been for the long run.

"Oh, I think the compiler is the one that compiles the code." Xiao Bai suddenly realizes.

"Please pay attention to your words, I'm not a thing, oh, no, I'm a thing, oh, it doesn't seem right, me."I.And the compiler itself is going to faint.

Compiler face of helplessness, meet such a person, I recognize today.

Whatever happens to little white, I thought I should consult the compiler after seeing it today.

Will the compiler help her?

 

 

(3)

 


Xiao Bai came up again and looked carefully before he could see that the compiler was eating Java source code and pulling a class (byte code) file.

Well, why is this code so familiar, not the ones I just wrote."Stop, stop, stop."The compiler was stopped by Xiao Bai.

"What are you doing again?"Compiler to.

"Hee-hee, I wrote this code, I want to see how it was compiled," Xiao Bai to.

The compiler looked at the code. It was so "simple" that she was definitely a newbie.Alas, let her see.

However, the compiler said, "The whole compilation process is very complicated. It is impossible to find out what's inside, so it's only a busy day."

"The compiled content is binary data, or, more commonly, a long byte array (byte[])." The compiler continues, "Usually it is written to a file, which is a class file."

"But this is not necessary, it can also be transmitted to other places through the network, or it can be stored in memory and discarded when it is exhausted."

"Wow, that's okay." Xiao Bai was surprised.The compiler thought that you came out of the ditch, had never seen the world, and was surprised.

Continue to, "Structurally speaking, an array is a continuous space, it is'unstructured', just like a segment, the only thing you can do is access it by index."

Xiao Bai said, "There must be a lot of compiled content in an array. How do you know where everything is?"It's not all messy.

The compiler feels that Xiao Bai has slowly come up and has a little comfort in his heart, at least his own explanation will not be completely wasted.So continue to.

"So the JVM's bulls designed the byte code format and put it in a byte array."

Xiao Bai was curious, "How did that work?"

"Actually, there is nothing too deep. Since the arrays are positioned, set the order of all the contents and put them in the array one by one."

"If the length of the content is fixed (i.e. fixed), it is simplest and can be put in directly."

"If the length of the content is not fixed (i.e., lengthened), it is also very simple. Use one or two bytes to store the length of the content before it is OK."

 

 

(4)

 


"The first four bytes of a byte code must be a fixed number. Its decimal number is 3405691582. Most people are more familiar with its hexadecimal number, 0xCAFEBABE."

"Usually called Magic, it is used to distinguish file types," the compiler says.

"Is not an extension (commonly known as a suffix) used to distinguish file types"?Xiao Bai said,'For example,.Java is a Java file,.class is a byte code file'.

"Extensions can really be distinguished, but most are for the operating system or for people to see.As we can see when.mp3 is audio,.mp4 is video, and.txt is text file.

"Operating systems can associate software that opens them with extensions, such as.docx, which opens with word instead of text files."The compiler continues to.

"Another problem is that extensions can be easily modified, such as manually changing a.java to a.class. What happens if the JVM loads this fake class file?"

"That JVM reads the first four bytes and finds that it is not the magic number just mentioned, which means that it is not a legal class file and throws an exception directly," Xiao Bai said.

"Good, it's really pedagogical," the compiler said. "But there's one more problem, I don't know if you noticed it?Four bytes correspond to the Java int type, and the maximum value of the int type is 214783647.

"But the value of magic number has exceeded the maximum value of int, how can it be put down, won't it overflow?"

"Really, how come I didn't find it, and how did it really go about?"Small white to.

"In fact, it is not worth mentioning that JVM treats it as an unsigned number.Java is treated as a signed number.The maximum value of an unsigned number is basically twice the maximum value of a signed number.

"The next four bytes are version numbers, which may vary slightly from version to version, followed by runtime checks, such as JDK8 compiled byte codes that cannot be run on JDK7."

"The first two of these four bytes are minor versions and the last two are major versions."The compiler goes on to, "For example, the JDK version I'm using now is 1.8.0_211, that version was 0, and the main version was 52".

"So the first eight bytes are 0xCAFEBABE, 0, 52, they're not in the source code."

Magic [getMagic()=0xcafebabe]
MinorVersion [getVersion()=0]
MajorVersion [getVersion()=52]



 

(5)

 


When the compiler reads the public class in the source code, it goes to a table, as shown below:


public corresponds to ACC_PUBLIC, value 0x0001, class defaults to, then reads ACC_The value of SUPER is 0x0020.

"Finally put them together (bitwise or operational), 0x0001 | 0x0020 => 0x0021, and save this value, which is the access control flag for this class."

Xiao Bai has opened his eyes this time, but there is still something unknown, "This ACC_What kind of ghost is SUPER"?

The compiler explains, "This is a legacy of history, and it was meant to be handled specially when a parent method was called, but it is now ignored and ignored."

Then I read about Apple, which is the class name.The compiler first gets the full name of the class.org.cnt.java.Apple.

Then I'll take a little bit of it and change it to org/cnt/java/Apple, "that's what class names are in byte code."

The compiler finds that this Apple class does not explicitly inherit the parent class, indicating that it inherits from the Object class, and gets its full name, java/lang/Object.

Next, you read about implements Fruit, which implements the Fruit interface and gets the full name, org/cnt/java/Fruit.

Xiao Bai said, "These are easier to understand. Replacing the dot (.) with the forward slash (/) in the full name is certainly a historical reason.But how can this information be stored in an array"?

"Replacing dots with forward slashes is really a historical cause," the compiler proceeds to, "These strings are class or interface names, but they are strings in nature, and class and interface names are just meanings given to them."

"In addition, field names and method names are also strings. Similarly, field names and method names give it meaning.So strings are basic data and need to be supported.

"In addition to strings, there are integer numbers, floating-point numbers, which are basic data and need to be supported."

As a result, designers have devised several types, such as the following:


"On the left is the type name, which is easy to understand, and on the right is the corresponding value for storage," the compiler proceeds to.

"Here Integer/Long/Float/Double and Utf8 are used to store data specifically, representing integers/floats and strings.Most other types refer to strings and give them meaning.

"So the class name is first stored as a string, Utf8, whose value corresponds to 1."The compiler then goes on to say, "Since the string is a variable length, store the length of the string in two bytes, followed by the specific string contents."

So this is the structure of the string, as shown in the following figure:


"Class name strings store data as 1, 18, org/cnt/java/Apple.The first byte is 1, indicating the Utf8 type, and the second and third bytes store 18, indicating that the string length is 18, followed by the true string.So share 1 + 2 + 18 => 21 bytes.

"The parent name string is stored as 1, 16, java/lang/Object.19 bytes in total.

"Interface name strings are stored as 1, 18, org/cnt/java/Fruit.21 bytes in total.

Xiao Bai couldn't hear it. The compiler took a breath and went on explaining.

"Once the strings are saved, it's time to give them meaning. References to these strings must be involved in subsequent operations, so assign a number to each string as well."

For example, Apple is #2, 2, Object is #4, Fruit is #6.

"Since all three strings are class or interface names, Class should be used as the design specification, with a corresponding value of 7, and then a string number can be specified."

So the class or interface is represented as follows:


"Class (interface) is indicated by one byte first, then the number of a string is stored by two bytes.The whole idea is straightforward, that is, to use this numbered string as a class or interface name.

"Classes are represented as, 7, #2.7 means Class and #2 means the storage number of the string of the class name.Three bytes in common.

"The parent class means, 7, #4.Three bytes in common.The interface is represented as, 7, #6.Three bytes in common.

In fact, each of these three classes is given a number so that they can be referenced elsewhere.

 

 

(6)

 


"These are constants, they are all in the constant pool, and their number is their index in the constant pool."The compiler said.

"Constant pools are known, at least heard of.But most people are not very familiar with it because very few people have seen it.

The compiler went on to say, "You're here today," and put the pool of constants generated by the compilation of lower-case classes on the table.

"What's this? That's so much. It's strange," Xiao Bai said. It's also the first time she's met.

ConstantPoolCount [getCount()=46]
ConstantPool [
#0 = null
#1 = ConstantClass [getNameIndex()=2, getTag()=7]
#2 = ConstantUtf8 [getLength()=18, getString()=org/cnt/java/Apple, getTag()=1]
#3 = ConstantClass [getNameIndex()=4, getTag()=7]
#4 = ConstantUtf8 [getLength()=16, getString()=java/lang/Object, getTag()=1]
#5 = ConstantClass [getNameIndex()=6, getTag()=7]
#6 = ConstantUtf8 [getLength()=18, getString()=org/cnt/java/Fruit, getTag()=1]
#7 = ConstantUtf8 [getLength()=4, getString()=name, getTag()=1]
#8 = ConstantUtf8 [getLength()=18, getString()=Ljava/lang/String;, getTag()=1]
#9 = ConstantUtf8 [getLength()=5, getString()=color, getTag()=1]
#10 = ConstantUtf8 [getLength()=1, getString()=I, getTag()=1]
#11 = ConstantUtf8 [getLength()=6, getString()=weight, getTag()=1]
#12 = ConstantUtf8 [getLength()=1, getString()=D, getTag()=1]
#13 = ConstantUtf8 [getLength()=6, getString()=<init>, getTag()=1]
#14 = ConstantUtf8 [getLength()=3, getString()=()V, getTag()=1]
#15 = ConstantUtf8 [getLength()=4, getString()=Code, getTag()=1]
#16 = ConstantMethodRef [getClassIndex()=3, getNameAndTypeIndex()=17, getTag()=10]
#17 = ConstantNameAndType [getNameIndex()=13, getDescriptorIndex()=14, getTag()=12]
#18 = ConstantDouble [getDouble()=0.5, getTag()=6]
#19 = null
#20 = ConstantFieldRef [getClassIndex()=1, getNameAndTypeIndex()=21, getTag()=9]
#21 = ConstantNameAndType [getNameIndex()=11, getDescriptorIndex()=12, getTag()=12]
#22 = ConstantUtf8 [getLength()=15, getString()=LineNumberTable, getTag()=1]
#23 = ConstantUtf8 [getLength()=18, getString()=LocalVariableTable, getTag()=1]
#24 = ConstantUtf8 [getLength()=4, getString()=this, getTag()=1]
#25 = ConstantUtf8 [getLength()=20, getString()=Lorg/cnt/java/Apple;, getTag()=1]
#26 = ConstantUtf8 [getLength()=7, getString()=getName, getTag()=1]
#27 = ConstantUtf8 [getLength()=20, getString()=()Ljava/lang/String;, getTag()=1]
#28 = ConstantFieldRef [getClassIndex()=1, getNameAndTypeIndex()=29, getTag()=9]
#29 = ConstantNameAndType [getNameIndex()=7, getDescriptorIndex()=8, getTag()=12]
#30 = ConstantUtf8 [getLength()=7, getString()=setName, getTag()=1]
#31 = ConstantUtf8 [getLength()=21, getString()=(Ljava/lang/String;)V, getTag()=1]
#32 = ConstantUtf8 [getLength()=16, getString()=MethodParameters, getTag()=1]
#33 = ConstantUtf8 [getLength()=8, getString()=getColor, getTag()=1]
#34 = ConstantUtf8 [getLength()=3, getString()=()I, getTag()=1]
#35 = ConstantFieldRef [getClassIndex()=1, getNameAndTypeIndex()=36, getTag()=9]
#36 = ConstantNameAndType [getNameIndex()=9, getDescriptorIndex()=10, getTag()=12]
#37 = ConstantUtf8 [getLength()=8, getString()=setColor, getTag()=1]
#38 = ConstantUtf8 [getLength()=4, getString()=(I)V, getTag()=1]
#39 = ConstantUtf8 [getLength()=3, getString()=()D, getTag()=1]
#40 = ConstantUtf8 [getLength()=4, getString()=(D)V, getTag()=1]
#41 = ConstantUtf8 [getLength()=10, getString()=SourceFile, getTag()=1]
#42 = ConstantUtf8 [getLength()=10, getString()=Apple.java, getTag()=1]
#43 = ConstantUtf8 [getLength()=25, getString()=RuntimeVisibleAnnotations, getTag()=1]
#44 = ConstantUtf8 [getLength()=21, getString()=Lorg/cnt/java/Health;, getTag()=1]
#45 = ConstantUtf8 [getLength()=12, getString()=Healthy fruit, getTag()=1]
]


"Two bytes are used in front of the constant pool to store the size of the constant pool, and it is important to remember that this size is not necessarily the number of constants in the pool.But subtracting 1 must be the largest index.

"Because the 0 position in the constant pool (#0) is never used, and there are Long and Double types where a constant accounts for two consecutive indexes (yes, historical reasons), the first index is actually used and the second index is always empty (see #18, #19)."

The compiler goes on to say that'#0'is special to mean'none', and other places can point to it if you want to express none.If an Object has no parent, its parent points to #0, that is, none.

"So constants start with #1.You can see what #1 to #6 are just mentioned above.The compiler said.

"You really learned a lot," Xiao Bai said. "Can you talk more about the constant pool?"The compiler had to go on.

 

 

(7)

 


"A constant pool is a container that holds all kinds of information and assigns a number (i.e. an index) to each information. If you want to use this information elsewhere, just use this number."

The compiler proceeds to, "This pool of constants is also known in some languages as a'symbol table', and this way of using numbers is also known as a'symbol reference'."

I believe that many students who like learning are familiar with the two words symbol table and symbol reference. Whether they really understood them before or not, they should at least understand them now.Because you've already seen it.

"There are many benefits to using this common pool and constant reference method. The easiest thing to think of is reuse, space saving and easy management."The compiler continues.

"For example, if there are 10 methods in a class and each method defines a local variable of length, then the name length will appear in the constant pool only once, and all 10 methods are references to it."

"If there is a method named length, it is also a reference to the same constant, because this length constant is just string data and has no definite meaning in itself. Its meaning comes from the constant that references it."

"Oh, that's it," Xiao Bai realized, "Symbol tables, symbol references, these"tall"terms, but just get the elements in the list according to the index." Ha-ha.

When the compiler saw Xiao Bai being so happy, he was ready to throw a question and "crush" her.So I said.

"Constant pools look very similar to arrays/lists, are containers and are accessed indexed.Why is a constant pool only called a symbol table, not an array or list of symbols?

Xiao Bai can't answer naturally.The compiler continues, "The English word for a table is Table.The only difference between it and an array/list is that the elements in the array/list have fixed lengths.The length of the elements in the table is irregular.

"Several constants in the constant pool are all longer, so they are tables naturally."

Xiao Bai nodded and thought to himself that this compiler was terrific and that I would never seem to be able to reach his height in my life.

The compiler goes on to say, "The first eight bytes of the byte code store magic numbers and versions, the next two (9 and 10) bytes store the size of the constant pool, and then the entire constant pool (starting at 11).

"The constant pool is so advanced because everything that follows depends on it and references it."

Following the constant pool is the basic information for this class, as follows:

"First use 2 bytes to store the above calculated access control flag, 0x0021."

"Then store this class's index in the constant pool with 2 bytes, which is #1."

"Then store the index of the parent class in the constant pool with 2 bytes, which is #3."

"Since there can be multiple interfaces, the number of interfaces is stored in two bytes since only one interface is implemented, so the number 1 is stored."

"The index of all interfaces in the constant pool is then stored, with 2 bytes per interface.Since only one interface is implemented, the stored index is #5.

AccessFlags [getAccessFlags()=0x21, getAccessFlagsString()=[ACC_PUBLIC, ACC_SUPER]]
ThisClass [getClassIndex()=1, getClassName()=org/cnt/java/Apple]
SuperClass [getClassIndex()=3, getClassName()=java/lang/Object]
InterfacesCount [getCount()=1]
Interfaces [getClassIndexes()=[5], getClassNames()=[org/cnt/java/Fruit]]

 

 

 

(8)

 


The compiler proceeds to "It's time to read the field information next".When you read private, go to the following table to find it:


Find ACC_PRIVATE, save its value below 0x0002, this is the access control flag of the field.

Next you read String, which is the type of field, and you'll put it in the constant pool with an index of #8.

You can see a Utf8 that says it's a string and the content is Ljava/lang/String; starts with an uppercase L and is semicolon; ends with a full type name in the middle, which is how class (object) types are represented in byte codes.

Next you read name, which is the name of the field as well as a string, and put it in the constant pool with the corresponding index #7.

The compiler said, "Now that the information for one field has been read, the remaining two fields are read in the same way."

"How should the information in that field be stored?"Xiao Bai asked."Don't worry," the compiler said, taking out the storage format of the field:


First 2 bytes are the access control flags, then 2 bytes are the index of the field name in the constant pool, and then 2 bytes are the index of the field description (that is, the type) in the constant pool.

The next two bytes are the number of attributes, then the specific attribute information.For example, if a field is marked with a comment, that comment information is put into the attribute information.

The compiler goes on to say, "Attribute information is more complex in byte code, so there's not much to say here."Then you can organize the data in a format.

Because a class can have more than one field, store the number of fields in two bytes first. This class has three fields, so store three.

The first field, 0x0002, #7, #8, 0.Eight bytes are shared because there is no attribute content automatically.

The second field is 0x0002, #9, #10, 0.8 bytes in total.

The second field is 0x0002, #11, #12, 0.8 bytes in total.

The compiler goes on to say, "So all three fields are stored in 2 + 8 + 8 => 26 bytes."

Xiao Bai said, "Now I basically understand the routine.In fact, some things are not as complex as you think.

"Complex things still exist, let's not consider them now," the compiler said. "There's another problem, I don't know if you found it."

The type of field color is int, but it changes to uppercase I in the constant pool. The same type of weight is double, but in the constant pool it is uppercase D.

Xiao Bai said, "Let me guess, int, double are data types in Java and I, D are their corresponding representations in JVM.Right"?

"You're smart," the compiler said, "There's actually a mapping table between Java and JVM about types," as follows:


There are two things to note."As mentioned above, classes are mapped to LClassName; in this form, such as Object mapped to Ljava/lang/Object;."

The second point is the array, which is represented by a pair of brackets ([]) in Java and a left bracket ([) in JVM.That is, [] is mapped to [.

"Multidimensional arrays are the same, [][][] is mapped to [[[].Then there are types, "Java puts types first, JVM puts types behind."For example, double[] is mapped to [D].

"double[][][] maps to [[[D].Similarly, "String[] maps to [Ljava/lang/String;, Object[][] maps to [Ljava/lang/Object;".

"I seem to understand that Java has its own specifications, and byte codes have their own specifications, and the mapping relationship between them is already defined."Xiao Bai goes on.

"As long as you follow this mapping relationship, you can convert Java source code to byte code.Yes"?

"Roughly speaking, it can be understood that this is actually compiled, but it must be clear that true compilation is a very complex thing," the compiler said.

Xiao Bai said, "After the field is finished, you can be sure of this method. Let me try it again."

"Young man, it's fierce. Come and try it."The compiler said.

FieldsCount [getCount()=3]
Fields [
#0 = FieldInfo [getAccessFlags()=FieldAccessFlags [getAccessFlags()=0x2, getAccessFlagsString()=[ACC_PRIVATE]], getNameIndex()=7, getName()=name, getDescriptorIndex()=8, getDescriptor()=Ljava/lang/String;, getAttributesCount()=0, getAttributes()=[]]
#1 = FieldInfo [getAccessFlags()=FieldAccessFlags [getAccessFlags()=0x2, getAccessFlagsString()=[ACC_PRIVATE]], getNameIndex()=9, getName()=color, getDescriptorIndex()=10, getDescriptor()=I, getAttributesCount()=0, getAttributes()=[]]
#2 = FieldInfo [getAccessFlags()=FieldAccessFlags [getAccessFlags()=0x2, getAccessFlagsString()=[ACC_PRIVATE]], getNameIndex()=11, getName()=weight, getDescriptorIndex()=12, getDescriptor()=D, getAttributesCount()=0, getAttributes()=[]]
]

 

 

 

(9)

 


"The method must have its own format, so you can find it and see it."

"Well, I'll find it," the compiler grinned bitterly.I am ashamed that a compiler in my hall has become Xiao Bai's assistant today.

The compiler found it and placed it on the table:


"Well, how exactly the same as the field". Small white to.That's easier.

First the access control flag, then the method name index, then the method description index, and finally the properties associated with the method.Then the cat paints the tiger, and the little white begins.

Read the public keyword first, which is an access control modifier. There must also be a table and its corresponding value for this keyword.

The compiler found the table before waiting for a small white opening:


White continues, ACC_The value corresponding to PUBLIC is 0x0001, so save this value first.

Then there's the name of the method, getName, which is a string that is routinely stored in the constant pool and has an index called #26.

Then the description of the method shows that Xiao Bai thinks that the method and the field are different. Besides the return type, there are also parameters. How about that?

So I ask the compiler, "Should the description of the method be formatted as well?"

"You're getting smarter and smarter," the compiler said. "It's really easy. Let me put it in a nutshell."

"If you remove access controllers, method names, parameter names, and method bodies in Java, you will actually have'method signatures'."

For example, if there is no entry and no return value, that's what it looks like, void().

Return value is String, enter int, double, String, is such a person, String(int, double, String).

"This method signature is actually a description of the method in Java, similar to it in byte code, by placing the return type after it and removing commas between parameters."

So void() is mapped to () V, and it's important to note here that void corresponds to the uppercase letter V.

String(int, double, String) maps to (IDLjava/lang/String;)Ljava/lang/String;

"Not difficult, not difficult," Xiao Bai said, and then started again.

In this format, Xiao Bai also saves the description of the just method into the constant pool, and the index is #27.

Xiao Bai has sorted out all six methods according to this routine. Now it is time to write the data into the byte array according to the format.

New Programming Note: The code of the method corresponds to the instructions of the JVM, which is ignored here and may be added separately later.

The compiler reminds Xiao Bai, "Did you miss a method?"

Xiao Bai looked at the Java source code again and counted it carefully. There are six. That's right.

The compiler says, have you ever seen a sentence like, "When a class has no constructor defined, the compiler generates a default parameterless constructor for it".

Xiao Bai nodded quickly, "Well, well, I've seen it."

"That's it," said the compiler, "but it's important to note that the names of constructors in byte code are <init> and the return types are V."

"That's the rule," Xiao Bai said, nodding the compiler.

The compiler adds, "There is actually parameter information for the method, such as parameter location, parameter type, parameter name, parameter access control flags, etc."

"This information is put in the last attribute information in the method format, let's not talk about it for a moment."

New programming notes:

Before JDK7, the byte code did not contain the method's parameter name.Because parameters are passed in by location when the JVM executes instructions, parameter names are not useful for code execution.

Since more and more frameworks are numerically bound by method parameter names, Java has had to include support for parameter names in JDK8.

However, you need to set the compiler's - parameters parameter so that the method parameter name can also be put in byte code.

You can see that #32;in the constant pool is a "MethodParameters" string, indicating that the byte code already contains the parameter name.

The three strings #7, #9, and #11in the constant pool are parameter names as well as field names, which is the benefit of reuse.

New programming note: The format of the method is exactly the same as that of the field, so the writing process is no longer demonstrated.

So there are seven methods in this class.

MethodsCount [getCount()=7]
Methods [
#0 = MethodInfo [getAccessFlags()=MethodAccessFlags [getAccessFlags()=0x1, getAccessFlagsString()=[ACC_PUBLIC]], getNameIndex()=13, getName()=<init>, getDescriptorIndex()=14, getDescriptor()=()V, getAttributesCount()=1, getAttributes()=[Code [getMaxStack()=3, getMaxLocals()=1, getCodeLength()=12, getJvmCode()=JvmCode [getCode()=12], getExceptionTableLength()=0, getExceptionTables()=[], getAttributesCount()=2, getAttributes()=[LineNumberTable [getLineNumTableLength()=3, getLineNumTables()=[LineNumTable [getStartPc()=0, getLineNumber()=8], LineNumTable [getStartPc()=4, getLineNumber()=12], LineNumTable [getStartPc()=11, getLineNumber()=8]]], LocalVariableTable [getLocalVarTableLength()=1, getLocalVarTables()=[LocalVarTable [getStartPc()=0, getLength()=12, getNameIndex()=24, getDescriptorIndex()=25, getIndex()=0]]]]]]]
#1 = MethodInfo [getAccessFlags()=MethodAccessFlags [getAccessFlags()=0x1, getAccessFlagsString()=[ACC_PUBLIC]], getNameIndex()=26, getName()=getName, getDescriptorIndex()=27, getDescriptor()=()Ljava/lang/String;, getAttributesCount()=1, getAttributes()=[Code [getMaxStack()=1, getMaxLocals()=1, getCodeLength()=5, getJvmCode()=JvmCode [getCode()=5], getExceptionTableLength()=0, getExceptionTables()=[], getAttributesCount()=2, getAttributes()=[LineNumberTable [getLineNumTableLength()=1, getLineNumTables()=[LineNumTable [getStartPc()=0, getLineNumber()=16]]], LocalVariableTable [getLocalVarTableLength()=1, getLocalVarTables()=[LocalVarTable [getStartPc()=0, getLength()=5, getNameIndex()=24, getDescriptorIndex()=25, getIndex()=0]]]]]]]
#2 = MethodInfo [getAccessFlags()=MethodAccessFlags [getAccessFlags()=0x1, getAccessFlagsString()=[ACC_PUBLIC]], getNameIndex()=30, getName()=setName, getDescriptorIndex()=31, getDescriptor()=(Ljava/lang/String;)V, getAttributesCount()=2, getAttributes()=[Code [getMaxStack()=2, getMaxLocals()=2, getCodeLength()=6, getJvmCode()=JvmCode [getCode()=6], getExceptionTableLength()=0, getExceptionTables()=[], getAttributesCount()=2, getAttributes()=[LineNumberTable [getLineNumTableLength()=2, getLineNumTables()=[LineNumTable [getStartPc()=0, getLineNumber()=21], LineNumTable [getStartPc()=5, getLineNumber()=22]]], LocalVariableTable [getLocalVarTableLength()=2, getLocalVarTables()=[LocalVarTable [getStartPc()=0, getLength()=6, getNameIndex()=24, getDescriptorIndex()=25, getIndex()=0], LocalVarTable [getStartPc()=0, getLength()=6, getNameIndex()=7, getDescriptorIndex()=8, getIndex()=1]]]]], MethodParameters [getParametersCount()=1, getParameters()=[Parameter [getNameIndex()=7, getAccessFlags()=0x0]]]]]
#3 = MethodInfo [getAccessFlags()=MethodAccessFlags [getAccessFlags()=0x1, getAccessFlagsString()=[ACC_PUBLIC]], getNameIndex()=33, getName()=getColor, getDescriptorIndex()=34, getDescriptor()=()I, getAttributesCount()=1, getAttributes()=[Code [getMaxStack()=1, getMaxLocals()=1, getCodeLength()=5, getJvmCode()=JvmCode [getCode()=5], getExceptionTableLength()=0, getExceptionTables()=[], getAttributesCount()=2, getAttributes()=[LineNumberTable [getLineNumTableLength()=1, getLineNumTables()=[LineNumTable [getStartPc()=0, getLineNumber()=26]]], LocalVariableTable [getLocalVarTableLength()=1, getLocalVarTables()=[LocalVarTable [getStartPc()=0, getLength()=5, getNameIndex()=24, getDescriptorIndex()=25, getIndex()=0]]]]]]]
#4 = MethodInfo [getAccessFlags()=MethodAccessFlags [getAccessFlags()=0x1, getAccessFlagsString()=[ACC_PUBLIC]], getNameIndex()=37, getName()=setColor, getDescriptorIndex()=38, getDescriptor()=(I)V, getAttributesCount()=2, getAttributes()=[Code [getMaxStack()=2, getMaxLocals()=2, getCodeLength()=6, getJvmCode()=JvmCode [getCode()=6], getExceptionTableLength()=0, getExceptionTables()=[], getAttributesCount()=2, getAttributes()=[LineNumberTable [getLineNumTableLength()=2, getLineNumTables()=[LineNumTable [getStartPc()=0, getLineNumber()=31], LineNumTable [getStartPc()=5, getLineNumber()=32]]], LocalVariableTable [getLocalVarTableLength()=2, getLocalVarTables()=[LocalVarTable [getStartPc()=0, getLength()=6, getNameIndex()=24, getDescriptorIndex()=25, getIndex()=0], LocalVarTable [getStartPc()=0, getLength()=6, getNameIndex()=9, getDescriptorIndex()=10, getIndex()=1]]]]], MethodParameters [getParametersCount()=1, getParameters()=[Parameter [getNameIndex()=9, getAccessFlags()=0x0]]]]]
#5 = MethodInfo [getAccessFlags()=MethodAccessFlags [getAccessFlags()=0x1, getAccessFlagsString()=[ACC_PUBLIC]], getNameIndex()=11, getName()=weight, getDescriptorIndex()=39, getDescriptor()=()D, getAttributesCount()=1, getAttributes()=[Code [getMaxStack()=2, getMaxLocals()=1, getCodeLength()=5, getJvmCode()=JvmCode [getCode()=5], getExceptionTableLength()=0, getExceptionTables()=[], getAttributesCount()=2, getAttributes()=[LineNumberTable [getLineNumTableLength()=1, getLineNumTables()=[LineNumTable [getStartPc()=0, getLineNumber()=35]]], LocalVariableTable [getLocalVarTableLength()=1, getLocalVarTables()=[LocalVarTable [getStartPc()=0, getLength()=5, getNameIndex()=24, getDescriptorIndex()=25, getIndex()=0]]]]]]]
#6 = MethodInfo [getAccessFlags()=MethodAccessFlags [getAccessFlags()=0x1, getAccessFlagsString()=[ACC_PUBLIC]], getNameIndex()=11, getName()=weight, getDescriptorIndex()=40, getDescriptor()=(D)V, getAttributesCount()=2, getAttributes()=[Code [getMaxStack()=3, getMaxLocals()=3, getCodeLength()=6, getJvmCode()=JvmCode [getCode()=6], getExceptionTableLength()=0, getExceptionTables()=[], getAttributesCount()=2, getAttributes()=[LineNumberTable [getLineNumTableLength()=2, getLineNumTables()=[LineNumTable [getStartPc()=0, getLineNumber()=39], LineNumTable [getStartPc()=5, getLineNumber()=40]]], LocalVariableTable [getLocalVarTableLength()=2, getLocalVarTables()=[LocalVarTable [getStartPc()=0, getLength()=6, getNameIndex()=24, getDescriptorIndex()=25, getIndex()=0], LocalVarTable [getStartPc()=0, getLength()=6, getNameIndex()=11, getDescriptorIndex()=12, getIndex()=1]]]]], MethodParameters [getParametersCount()=1, getParameters()=[Parameter [getNameIndex()=11, getAccessFlags()=0x0]]]]]
]


New Programming Note: The method part outputs a lot because it contains information about the code of the method body.

 

 

(10)

 


"It's awesome after birth," the compiler said."Xiao Bai can even follow the routine to do something."

The compiler is not at risk, though, because the core content is how executable code can be converted to instructions in the JVM instruction set, but dry "bottom of the box" can't be told to look good.Haha, O(_) O.

Then the compiler takes out a complete Byte Code file format picture to show the small white:


After reading it, Xiao Bai said, "Just like what he just said, there is also this attribute information in the end."

The compiler says, "Attribute information is a very complex content in a byte code file that can be temporarily ignored."

As mentioned above, at least the relevant content of the note is contained in the attribute information.

Let's see what kind of attribute information you've written about this class.

AttributesCount [getCount()=2]
Attributes [
#0 = SourceFile [getSourcefileIndex()=42]
#1 = RuntimeVisibleAnnotations [getNumAnnotations()=1, getAnnotations()=[Annotation [getTypeIndex()=44, getNumElementValuePairs()=1, getElementValuePairs()=[ElementValuePair [getElementNameIndex()=7, getElementValue()=ElementValue [getTag()=ElementValueTag [getTagChar()=s], getUnion()=ElementValueUnion [getConstValueIndex()=45]]]]]]]
]


The compiler goes on to say that there are two attribute information, the first being the name of the source code file, #42 in the constant pool.In fact, it is Apple.java Yes.

The second is annotation information visible at runtime. There is one annotation in this class. The annotation type is #44 in the constant pool.It's Lorg/cnt/java/Health; that's it.

The annotation explicitly sets a pair of attribute values.The attribute name is #7, or name, in the constant pool, and the type is lowercase s, which indicates the String type. The attribute value is #45, or Healthy Fruit.

These types in the following diagram are all types that can be used to annotate attributes:


Finally, the compiler prints out a line of information:

-----bytes=1085-----

Xiao Bai said, "What does this mean?""This is the total length of byte code generated after compilation, which is 1085 bytes," compiler to.

Xiao Bai just wanted to express his thanks to the compiler. Suddenly, he smelled a smell of meat.

PS: The last few words have not been written, please come and complete, Hee-hee.

 

 

>> Popular Articles Collection < < <

 

Ten years after graduation, I said

How do I interview people about List? It's a bit long

How did I become head of the Development Team in just one year after graduation

Dad gave birth to Spring MVC's younger brother Spring WebFlux

How do I "routine" other people when interviewing their Spring affairs

[Interview] Hematemesis at Spring Transaction Interview Points (recommended collection)

How do I "soften" someone's mind when interviewing them about Redis?

With all these Redis points in mind, the interviewer must think you're NB (Dry | Recommended)

If you answer "What is thread safety," the interviewer will be impressed with you (Recommendations to keep)

Interview: A good article so far that is so clear and clear as Sync/Async/Block/Non-Block/BIO/NIO/AIO (Quick Store)

[Interview] An article helps you understand the past and present of I/O multiplexing and asynchronous I/O thoroughly (well-written, recommended collection)

If you treat threads as one person, all questions become clear in a flash

Java Multithreaded Customs Clearance - Fundamentals Challenge

Pin Spring: The Foundation of the Empire

 

 

 

The author is a code farmer who has worked for more than 10 years and is now an architect.Like to study technology, advocate simple and happy.Pursue explanatory techniques in easy-to-understand languages, and hope that all readers can understand and remember them.Following is the two-dimensional code of the public number, welcome to your attention!

 

Keywords: Java Attribute jvm Spring

Added by Kingw on Fri, 05 Jun 2020 03:51:28 +0300