ASM learning notes -- ASM 4 user guide Chapter 2 Key Points translation summary, asm -- asm

Source: Internet
Author: User

ASM learning notes -- ASM 4 user guide Chapter 2 Key Points translation summary, asm -- asm

Reference: ASM 4 user guide

 

Part 1 core API

Chapter 2

2.1.1 Overview

The compiled classes include:

L Description: includes the modifier (such as public or private), name, parent class, interface, or comment area.

L part of each domain declaration in the class.

L each method in the class and the part of the constructor declaration. It also contains the method-compiled code, which is a series of Java bytecode instructions.

The compiled class structure is as follows:

 

2.1.2 internal name (internal name)

Class or interface uses the internal name. The internal name is the full qualified name of the class, that is, the full name with a slash.

For example, the internal name of String is java/lang/String.

2.1.3 type descriptor

The internal name is used only for the class or interface name. Others use type descriptors.

 

String is Ljava/lang/String;

The class descriptor starts with L and ends with a semicolon.

The array type starts with square brackets.

 

2.1.4 method description

 

The method descriptor starts with parentheses and contains the type of each parameter (each parameter type is written in sequence without spaces or commas). The parentheses are followed by the return type of the method. The method descriptor does not include the method name and parameter name.

 

 

2.2 interfaces and components

2.2.1 description

The asm api is based on the ClassVistor abstract class for the generated and converted compiled classes. VisitField returns a FieldVistor, Which is recursive in FieldVistor.

The sequence of method calls in ClassVistor:

Visit visitSource? VisitOuterClass? (VisitAnnotation | visitAttribute )*

(VisitInnerClass | visitField | visitMethod )*

VisitEnd

Visit must be called first, followed by at most one visitSource, followed by at most one visitOuterClass, followed by any number of visitAnnotation and visitAttribute, followed by any number of visitInnerClass, visitField, and visitMethod, and finally called visitEnd.

 

ASM provides three core components based on ClassVisitor API to generate and convert classes,

L The ClassReader class parses the byte array of a given compiled class and calls the visitXXX method in the ClassVisitor instance. This ClassVistor instance is passed in as an accept parameter. It can be viewed as the event producer.

L ClassWriter class is a subclass of ClassVistor. It constructs the compiled class directly in binary format. It outputs a byte array including compiled classes (which can be obtained through the toByteArray method ). It is regarded as the consumer of the event.

L The ClassVistor class represents all method calls from other ClassVistor instances. It is regarded as the filter of events.

2.2.2 Parsing

The component required to parse an existing class is ClassReader. For example, we need to print the content of a class. First, we need to write a ClassVistor subclass to print the information of the class it accesses.

ClassPrinter cp = new ClassPrinter ();
ClassReader cr = new ClassReader ("java. lang. Runnable ");
Cr. accept (cp, 0 );

Because ClassPrinter is a subclass of ClassVistor, as mentioned above, the ClassReader accept method requires a ClassVistor, so cp is used as the accept parameter.

The running result is:

Java/lang/Runnable extends java/lang/Object {
Run () V
}

Note that there are many ways to build ClassReader instances. The class that can be accessed can be named by name (as shown in the preceding example), or use a byte array value or as an InputStream. You can use the getResourceAsStream method of ClassLoader to obtain an input stream. For example:

Cl. getResourceAsStream (classname. replace ('.', '/') + ". class ");

 

2.2.3 generate class

To generate a class, the only required component is the ClassWriter component.

You can use ClassLoader to dynamically load the generated class.

 

2.2.4 conversion class

The ClassReader and ClassWriter components are used together. The result is that the Class parsed by class reader will be rebuilt by Class writer.

Byte [] b1 = ...;
ClassWriter cw = new ClassWriter (0 );
// Cv forwards all events to cw
ClassVisitor cv = new ClassVisitor (ASM4, cw ){};
ClassReader cr = new ClassReader (b1 );
Cr. accept (Cv, 0 );
Byte [] b2 = cw. toByteArray (); // b2 represents the same class as b1

Optimization:

Using the above method, only the jdk version has been modified, and most of them have not changed. B2 is built by capturing b1. A more efficient method is to directly copy the part that does not need to be changed. In this way, this part does not need to be parsed and generates response events. ASM can automatically perform such optimization.

 

 

2.2.5 delete a class member

If you do not forward a function call, the corresponding class element is removed.

However, this policy does not work for fields and methods, because the visitField and visitMethod methods must have a return value, so return a null value.

Note: To specify a method, you must specify both the expenditure function name and descriptor. Because many methods may have the same name but different parameters.

2.2.6 Add a class member

Different from calling a method without forwarding, more Forwarding is equivalent to adding some class elements.

Note: in fact theonly truly correct solution is to add new members by making additional callinthe visitEnd method. indeed a class must not contain duplicate members, and theonly way to be sure that a new member is unique is to compare it with all the existingmembers, which can only be done once they have all been visited, I. e. in thevisitEnd method. this is rather constraining. using generated names that areunlikely to be used by a programmer, such as _ counter $ or _ 4B7F _ is sufficient inpractice to avoid duplicate members without having to add them in visitEnd. note that, as discussed in the first chapter, the tree API does not have thislimitation: it is possible to add new members at any time inside atransformation with this API.

Example: Add a variable. In visitField, check whether the variable to be added already exists. If not, add the variable to the visitEnd method.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.