The code that the JVM understands is called bytecode (.class files). Java, Clojure, Groovy, Scala, JRuby and other languages are compiled by a compiler into bytecode and run on a virtual machine.

A classfile is defined as a classfile, a C-like structure that records information such as the current class, parent class, interface, field properties, methods, and so on.

ClassFile { u4 magic; //Class file flag U2 minor_version; U2 major_version; // U2 major_version; // U2 constant_pool_count; Cp_info constant_pool[constant_pool_count-1]; // constant pool u2 access_flags; //Class access flag u2 this_class; // Current class U2 super_class; // U2 interfaces_count; // U2 interfaces[interfaces_count]; // A class can implement more than one interface; Field_info fields[fields_count]; field_info fields[fields_count]; field_info fields[fields_count]; // A class can have multiple fields u2 methods_count; // the number of methods in the Class file method_info methods[methods_count]; // A class can have multiple methods U2 attributes_count; Attribute_info attributes[attributes_count]; // Attributes [attributes_count]; // Property sheet collection}



magic

The first four bytes of each Class file are called the Magic Number, and their only purpose is to determine whether the file is a Class file that can be received by the virtual machine.

The version number

The next four bytes of the magic number store the version numbers of the Class file: bits 5 and 6 are the minor version numbers, and bits 7 and 8 are the major version numbers.

Each time a major release of Java (e.g. Java 8, Java9) is released, the major release number is incremented by 1. You can use the javap-v command to quickly view the version number information of the Class file.

A higher version of the Java virtual machine can execute Class files generated by a lower version of the compiler, but a lower version of the Java virtual machine cannot execute Class files generated by a higher version of the compiler. Therefore, we need to make sure that the version of the JDK we are developing is the same as the version of the JDK in our production environment during actual development. Constant pool Literal text string, declared as a constant symbol of final reference: classes and the fully qualified name of the interface, the names of the name of the field and method descriptors, and descriptors access tokens After the end of the constant pool, followed by two bytes to represent access to sign, the sign is used to identify some of the class or interface levels of access to information, including: Whether the Class is a Class or an interface, whether it is a public or abstract type, and if it is a Class, whether it is declared final, and so on.

Class access and property modifiers:



field

Describes the variables declared in an interface or class, including class-level variables and instance variables, excluding local variables declared inside a method. Class variables have a static modifier, and instance variables have no static modifier.

Structure of the field:

  • access_flags: The scope of the field (public,private,protected modifiers), is it an instance variable or a class variable (static modifier), can it be serialized (transient modifier), can it be final, can it be visible (volatile modifier) Whether to force reads and writes from main memory).
  • Name_index: A reference to the constant pool, representing the name of the field;
  • Descriptor_index: a reference to a pool of constants, representing the field and method descriptors;
  • Attributes_count: A field has some additional attributes. Attributes_count holds the number of attributes;
  • Attributes [attributes_count]: Holds the concrete content of the concrete attribute.
  • Each of the modifiers in the above information is a Boolean value, with or without a modifier, which is a good place to use the flag bit. The name of the field and the data type of the field are not fixed, and can only be described by referring to the constants in the constant pool.
  • The access_flag value of the field:

The method Class file storage format describes methods in almost exactly the same way that fields are described. The method table has the same structure as the field table, including access flags, name indexes, descriptor indexes, and property sheet collections in turn.

The structure of method_info:



The access_flag value of the method table is:



Note: Because volatile and transient modifiers cannot modify methods, the access flags for volatile and transient modifiers are missing from the method table, but keyword modifiers such as synchronized, native, and abstract have been added to the method table to add flags for these keywords.

attribute

You can carry your own collection of property sheets in the Class text, field table, and method table to describe certain scenario-specific information. With others in the Class file data sequence, the length and content of different project requirements, the limitation of property sheet set slightly loose, the order of the table for each attribute has a strict no longer, and as long as you don’t with the attribute name repetition, anyone to realize the compiler can be to write their attributes in the table definition of attribute information, The Java Virtual Machine will ignore properties that it does not recognize.