Search code examples
javajava-bytecode-asm

MethodVisitor's (api, MethodVisitor) constructor, is it needed for only reading


I am only reading bytecode not overwrite,

which one I should use:

public MethodVisitor visitMethod(...) {
   return new MyMethodVisitor(Opcodes.ASM9, super.visitMethod(...));
}

or

public MethodVisitor visitMethod(...) {
   return new MyMethodVisitor(Opcodes.ASM9);
}

Solution

  • ASM’s visitors support chaining. When you pass another class visitor to the ClassVisitor constructor, it will be stored in the cv field. Then, the visitMethod method will check that field and if non-null, delegate to the next class visitor and return whatever that visitMethod call returned.

    So when you do not chain another class visitor, the effect of both variants will be the same. The super.visitMethod(...) call will return null then and passing null to the method visitor constructor has the same effect as calling the constructor without a delegate (I’m assuming that your subclass constructors delegate to MethodVisitor’s constructor 1:1).

    If you want to design your classes to support delegation, even if you’re not using it now in this specific scenario, you have to keep in mind that all overridden methods of the MethodVisitor also have to call the corresponding super method correctly.

    If you don’t do this, it’s better not to support delegation at all, rather than having inconsistent calls to the next visitor. In this case, use the second variant but also make the lack of this support clear, by only providing constructors without visitor parameter in the first place, in both, your class visitor subclass and your method visitor subclass.