因此,使用下面的代码,我的输出是:
Starting application with the Agent
Visiting class: HelloWorld
Class Major Version: 51
Super class: java/lang/Object
Source: HelloWorld.java
Method: <init> desc = ()V cv = com.amir.agent.instrumentor.amirClassVisitor$1@79f1d448 and mv = null
Method: main desc = ([Ljava/lang/String;)V cv = com.amir.agent.instrumentor.amirClassVisitor$1@79f1d448 and mv = null
Method: foo desc = ()V cv = com.amir.agent.instrumentor.amirClassVisitor$1@79f1d448 and mv = null
Method ends here
Done instrumenting: HelloWorld
这让我很困惑。为什么我的methodVisitor
会null
?当null
为methodVisitor
时,ASM源代码似乎仅返回classVisitor
的{{1}},这在我的情况下是不正确的。
null
编辑:
我将此代码称为:
package com.amir.agent.instrumentor;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class amirClassVisitor {
private byte[] outData = null;
public amirClassVisitor() {
}
public void performInstrumentation(final String className,
final byte[] classAsBytes) {
final ClassVisitor cl = new ClassVisitor(Opcodes.ASM4) {
@Override
public void visit(final int version,
final int access,
final String name,
final String signature,
final String superName,
final String[] interfaces) {
System.out.println("Visiting class: "+name);
System.out.println("Class Major Version: "+version);
System.out.println("Super class: " + superName);
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public void visitOuterClass(final String owner,
final String name,
final String desc) {
System.out.println("Outer class: "+owner);
super.visitOuterClass(owner, name, desc);
}
@Override
public AnnotationVisitor visitAnnotation(final String desc,
final boolean visible) {
System.out.println("Annotation: "+desc);
return super.visitAnnotation(desc, visible);
}
@Override
public void visitAttribute(final Attribute attr) {
System.out.println("Class Attribute: " + attr.type);
super.visitAttribute(attr);
}
@Override
public void visitInnerClass(final String name,
final String outerName,
final String innerName,
final int access) {
System.out.println("Inner Class: " + innerName + " defined in " + outerName);
super.visitInnerClass(name, outerName, innerName, access);
}
@Override
public FieldVisitor visitField(final int access,
final String name,
final String desc,
final String signature,
final Object value) {
System.out.println("Field: "+name+" "+desc+" value:"+value);
return super.visitField(access, name, desc, signature, value);
}
@Override
public void visitEnd() {
System.out.println("Method ends here");
super.visitEnd();
}
@Override
public MethodVisitor visitMethod(final int access,
final String name,
final String desc,
final String signature,
final String[] exceptions) {
final MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
System.out.println("Method: " +name+ " desc = " +desc+ " cv = " +this+ " and mv = " +mv);
return mv;
}
@Override
public void visitSource(final String source,
final String debug) {
System.out.println("Source: "+source);
super.visitSource(source, debug);
}
};
final ClassReader classReader = new ClassReader(classAsBytes);
classReader.accept(cl, 0);
System.out.println("Done instrumenting: " +className);
}
public byte[] result() {
return outData;
}
}
答案 0 :(得分:2)
您打印的内容不是“我的methodVisitor
”,而是super
visitMethod
调用返回的值,换句话说是ClassVisitor.visitMethod
返回的默认值:
<强>返回强>:
访问方法字节代码的对象,如果此类访问者对访问此方法的代码不感兴趣,则为null
。
由于抽象类ClassVisitor
没有实现任何操作,因此它没有兴趣访问该方法,因此null
是完美的返回值。
因此,您可以实例化实现所需行为的新MethodVisitor
。或者,由于您似乎打算对课程进行检测,因此请让您的班级访问者委托给您传递给ClassWriter
的super class constructor。这样,您将继承可以自定义的复制行为。然后,super.visitMethod
将返回非null
方法访问者,该访问者将复制该方法。