![](https://img.haomeiwen.com/i13935704/9cc898b9a3a8f5fb.png)
classReader.accept(classAdapter, ClassReader.SKIP_DEBUG);
![](https://img.haomeiwen.com/i13935704/05bdfe75ee7dcd8c.png)
accept() 方法中调用核心部分如下,使用了
for循环处理所有的method
:![](https://img.haomeiwen.com/i13935704/8b80ae548edb8ac3.png)
![](https://img.haomeiwen.com/i13935704/28e69d38cbdf2899.png)
![](https://img.haomeiwen.com/i13935704/67de57ff199ba126.png)
ClassReader调用accept()方法接受一个ClassVisitor类型的对象。
我们深入到accept()
方法中
public void accept(ClassVisitor classVisitor, Attribute[] attributePrototypes, int parsingOptions) {
Context context = new Context();
context.attributePrototypes = attributePrototypes;
context.parsingOptions = parsingOptions;
context.charBuffer = new char[this.maxStringLength];
char[] charBuffer = context.charBuffer;
int currentOffset = this.header;
int accessFlags = this.readUnsignedShort(currentOffset);
String thisClass = this.readClass(currentOffset + 2, charBuffer);
String superClass = this.readClass(currentOffset + 4, charBuffer);
String[] interfaces = new String[this.readUnsignedShort(currentOffset + 6)];
currentOffset += 8;
// for 循环中读取所有的innerClasse
int innerClassesOffset;
for(innerClassesOffset = 0; innerClassesOffset < interfaces.length; ++innerClassesOffset) {
interfaces[innerClassesOffset] = this.readClass(currentOffset, charBuffer);
currentOffset += 2;
}
innerClassesOffset = 0;
int enclosingMethodOffset = 0;
String signature = null;
String sourceFile = null;
String sourceDebugExtension = null;
int runtimeVisibleAnnotationsOffset = 0;
int runtimeInvisibleAnnotationsOffset = 0;
int runtimeVisibleTypeAnnotationsOffset = 0;
int runtimeInvisibleTypeAnnotationsOffset = 0;
int moduleOffset = 0;
int modulePackagesOffset = 0;
String moduleMainClass = null;
String nestHostClass = null;
int nestMembersOffset = 0;
Attribute attributes = null;
int currentAttributeOffset = this.getFirstAttributeOffset();
int fieldsCount;
for(fieldsCount = this.readUnsignedShort(currentAttributeOffset - 2); fieldsCount > 0; --fieldsCount) {
String attributeName = this.readUTF8(currentAttributeOffset, charBuffer);
int attributeLength = this.readInt(currentAttributeOffset + 2);
currentAttributeOffset += 6;
if ("SourceFile".equals(attributeName)) {
sourceFile = this.readUTF8(currentAttributeOffset, charBuffer);
} else if ("InnerClasses".equals(attributeName)) {
innerClassesOffset = currentAttributeOffset;
} else if ("EnclosingMethod".equals(attributeName)) {
enclosingMethodOffset = currentAttributeOffset;
} else if ("NestHost".equals(attributeName)) {
nestHostClass = this.readClass(currentAttributeOffset, charBuffer);
} else if ("NestMembers".equals(attributeName)) {
nestMembersOffset = currentAttributeOffset;
} else if ("Signature".equals(attributeName)) {
signature = this.readUTF8(currentAttributeOffset, charBuffer);
} else if ("RuntimeVisibleAnnotations".equals(attributeName)) {
runtimeVisibleAnnotationsOffset = currentAttributeOffset;
} else if ("RuntimeVisibleTypeAnnotations".equals(attributeName)) {
runtimeVisibleTypeAnnotationsOffset = currentAttributeOffset;
} else if ("Deprecated".equals(attributeName)) {
accessFlags |= 131072;
} else if ("Synthetic".equals(attributeName)) {
accessFlags |= 4096;
} else if ("SourceDebugExtension".equals(attributeName)) {
sourceDebugExtension = this.readUtf(currentAttributeOffset, attributeLength, new char[attributeLength]);
} else if ("RuntimeInvisibleAnnotations".equals(attributeName)) {
runtimeInvisibleAnnotationsOffset = currentAttributeOffset;
} else if ("RuntimeInvisibleTypeAnnotations".equals(attributeName)) {
runtimeInvisibleTypeAnnotationsOffset = currentAttributeOffset;
} else if ("Module".equals(attributeName)) {
moduleOffset = currentAttributeOffset;
} else if ("ModuleMainClass".equals(attributeName)) {
moduleMainClass = this.readClass(currentAttributeOffset, charBuffer);
} else if ("ModulePackages".equals(attributeName)) {
modulePackagesOffset = currentAttributeOffset;
} else if (!"BootstrapMethods".equals(attributeName)) {
Attribute attribute = this.readAttribute(attributePrototypes, attributeName, currentAttributeOffset, attributeLength, charBuffer, -1, (Label[])null);
attribute.nextAttribute = attributes;
attributes = attribute;
}
currentAttributeOffset += attributeLength;
}
// classVisitor.visit()
classVisitor.visit(this.readInt(this.cpInfoOffsets[1] - 7), accessFlags, thisClass, signature, superClass, interfaces);
// classVisitor.visitSource
if ((parsingOptions & 2) == 0 && (sourceFile != null || sourceDebugExtension != null)) {
classVisitor.visitSource(sourceFile, sourceDebugExtension);
}
if (moduleOffset != 0) {
this.readModuleAttributes(classVisitor, context, moduleOffset, modulePackagesOffset, moduleMainClass);
}
// classVisitor.visitNestHost
if (nestHostClass != null) {
classVisitor.visitNestHost(nestHostClass);
}
// classVisitor.visitOuterClass
int methodsCount;
String annotationDescriptor;
if (enclosingMethodOffset != 0) {
String className = this.readClass(enclosingMethodOffset, charBuffer);
methodsCount = this.readUnsignedShort(enclosingMethodOffset + 2);
annotationDescriptor = methodsCount == 0 ? null : this.readUTF8(this.cpInfoOffsets[methodsCount], charBuffer);
String type = methodsCount == 0 ? null : this.readUTF8(this.cpInfoOffsets[methodsCount] + 2, charBuffer);
classVisitor.visitOuterClass(className, annotationDescriptor, type);
}
if (runtimeVisibleAnnotationsOffset != 0) {
fieldsCount = this.readUnsignedShort(runtimeVisibleAnnotationsOffset);
for(methodsCount = runtimeVisibleAnnotationsOffset + 2; fieldsCount-- > 0; methodsCount = this.readElementValues(classVisitor.visitAnnotation(annotationDescriptor, true), methodsCount, true, charBuffer)) {
annotationDescriptor = this.readUTF8(methodsCount, charBuffer);
methodsCount += 2;
}
}
if (runtimeInvisibleAnnotationsOffset != 0) {
fieldsCount = this.readUnsignedShort(runtimeInvisibleAnnotationsOffset);
for(methodsCount = runtimeInvisibleAnnotationsOffset + 2; fieldsCount-- > 0; methodsCount = this.readElementValues(classVisitor.visitAnnotation(annotationDescriptor, false), methodsCount, true, charBuffer)) {
annotationDescriptor = this.readUTF8(methodsCount, charBuffer);
methodsCount += 2;
}
}
if (runtimeVisibleTypeAnnotationsOffset != 0) {
fieldsCount = this.readUnsignedShort(runtimeVisibleTypeAnnotationsOffset);
for(methodsCount = runtimeVisibleTypeAnnotationsOffset + 2; fieldsCount-- > 0; methodsCount = this.readElementValues(classVisitor.visitTypeAnnotation(context.currentTypeAnnotationTarget, context.currentTypeAnnotationTargetPath, annotationDescriptor, true), methodsCount, true, charBuffer)) {
methodsCount = this.readTypeAnnotationTarget(context, methodsCount);
annotationDescriptor = this.readUTF8(methodsCount, charBuffer);
methodsCount += 2;
}
}
if (runtimeInvisibleTypeAnnotationsOffset != 0) {
fieldsCount = this.readUnsignedShort(runtimeInvisibleTypeAnnotationsOffset);
for(methodsCount = runtimeInvisibleTypeAnnotationsOffset + 2; fieldsCount-- > 0; methodsCount = this.readElementValues(classVisitor.visitTypeAnnotation(context.currentTypeAnnotationTarget, context.currentTypeAnnotationTargetPath, annotationDescriptor, false), methodsCount, true, charBuffer)) {
methodsCount = this.readTypeAnnotationTarget(context, methodsCount);
annotationDescriptor = this.readUTF8(methodsCount, charBuffer);
methodsCount += 2;
}
}
// classVisitor.visitAttribute
while(attributes != null) {
Attribute nextAttribute = attributes.nextAttribute;
attributes.nextAttribute = null;
classVisitor.visitAttribute(attributes);
attributes = nextAttribute;
}
// classVisitor.visitNestMember
if (nestMembersOffset != 0) {
fieldsCount = this.readUnsignedShort(nestMembersOffset);
for(methodsCount = nestMembersOffset + 2; fieldsCount-- > 0; methodsCount += 2) {
classVisitor.visitNestMember(this.readClass(methodsCount, charBuffer));
}
}
// classVisitor.visitInnerClass
if (innerClassesOffset != 0) {
fieldsCount = this.readUnsignedShort(innerClassesOffset);
for(methodsCount = innerClassesOffset + 2; fieldsCount-- > 0; methodsCount += 8) {
classVisitor.visitInnerClass(this.readClass(methodsCount, charBuffer), this.readClass(methodsCount + 2, charBuffer), this.readUTF8(methodsCount + 4, charBuffer), this.readUnsignedShort(methodsCount + 6));
}
}
fieldsCount = this.readUnsignedShort(currentOffset);
// this.readField(classVisitor)
for(currentOffset += 2; fieldsCount-- > 0; currentOffset = this.readField(classVisitor, context, currentOffset)) {
;
}
methodsCount = this.readUnsignedShort(currentOffset);
// this.readMethod(classVisitor)
for(currentOffset += 2; methodsCount-- > 0; currentOffset = this.readMethod(classVisitor, context, currentOffset)) {
;
}
// visitEnd()
classVisitor.visitEnd();
}
那么我们的逻辑(NameMethodVisitor)到底在哪里被执行到了?
// 定义一个自己的方法访问类
public static class NameMethodVisitor extends MethodVisitor {
public NameMethodVisitor(MethodVisitor mv) {
super(Opcodes.ASM7, mv); //???
}
public NameMethodVisitor(int api) {
super(api);
}
public NameMethodVisitor(int api, MethodVisitor methodVisitor) {
super(api, methodVisitor);
}
// 在源方法前去修改方法内容,这部分的修改将加载源方法的字节码之前
@Override
public void visitCode() {
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitLdcInsn("yy");
mv.visitFieldInsn(Opcodes.PUTFIELD, "asm5/Person", "name", "Ljava/lang/String;");
}
}
![](https://img.haomeiwen.com/i13935704/09287f5f225d620a.png)
让我们再看看visitoCode()是如何执行的。
![](https://img.haomeiwen.com/i13935704/5c58d9874119f4b6.png)
visitMethod() 访问了init()方法(即构造方法)
![](https://img.haomeiwen.com/i13935704/e1f10ec5d42c0934.png)
网友评论