A brief analysis of java bytecode framework ASM operating bytecode method
- 2020-06-01 09:39:27
- OfStack
We have introduced ASM in detail before, and those who need it can click here: an in-depth study of java bytecode framework ASM
JVM's type signature comparison table
Type Signature | Java Type |
---|---|
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
L | fully-qualified-class ;fully-qualified-class |
[ type | type[] |
( arg-types ) ret-type | method type |
For example, the java method is
long f (int n, String s, int[] arr);
The corresponding type signature is
f (ILjava/lang/String;[I)J
Another example is the java method
private void hi(double a, List<String> b);
The corresponding type signature is
hi (DLjava/util/List;)V
Next, ASM can be used to verify whether the above two types of signatures are correct:
public class Test {
public static void main(String[] args) throws Exception {
ClassPrinter printer = new ClassPrinter();
// Read the static inner class Bazhang
ClassReader cr = new ClassReader("Test$Bazhang");
cr.accept(printer, 0);
}
// Static inner class
static class Bazhang {
public Bazhang(int a) {
}
private long f (int n, String s, int[] arr){
return 0;
}
private void hi(double a, List<String> b){
}
}
static class ClassPrinter extends ClassVisitor {
public ClassPrinter() {
super(Opcodes.ASM5);
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
// Print out the parent class name And this kind of name
System.out.println(superName + " " + name);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// Print out the method name and type signature
System.out.println(name + " " + desc);
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
}
The last thing you print out:
java/lang/Object Test$Bazhang
<init> ()V
f (ILjava/lang/String;[I)J
hi (DLjava/util/List;)V
Verify the previous correctness, where you can see that the default constructor is also printed.
So, to do something interesting, let's add a and method to the Bazhang class, which is:
public void newFunc(String str){
}
This time you need to use ClassWriter, used to concatenate bytecode, ClassReader, ClassVisitor, ClassWriter articles can see this article: ASM source learning ClassReader, ClassVisitor and ClassWriter details
public static void main(String[] args) throws Exception {
ClassReader cr = new ClassReader(Bazhang.class.getName());
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
cr.accept(cw, Opcodes.ASM5);
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "newFunc", "(Ljava/lang/String;)V", null, null);
mv.visitInsn(Opcodes.RETURN);
mv.visitEnd();
// Get generated class File corresponding 2 Base flow
byte[] code = cw.toByteArray();
// will 2 The base stream writes out/ Under the
FileOutputStream fos = new FileOutputStream("out/Bazhang222.class");
fos.write(code);
fos.close();
}
This will generate Bazhang222.class in the out/ folder:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.util.List;
class Test$Bazhang {
Test$Bazhang() {
}
private long f(int n, String s, int[] arr) {
return 0L;
}
private void hi(double a, List<String> b) {
}
public void newFunc(String var1) {
}
}
Before finishing JVM instruction set, using bytecode ASM direct operation is no problem, at the end of the enclosed ASM source download address: http: / / forge ow2. org/projects asm /
conclusion
The above is the whole content of this article, I hope the content of this article to your study or work can bring 1 definite help, if you have questions you can leave a message to communicate.