Tri*_*ind 0 java bytecode cglib javassist byte-buddy
我想列出一个方法调用的所有方法。
void create() throws MyException {
System.out.println("TEST");
of("String").map(String::valueOf).get();
}
Run Code Online (Sandbox Code Playgroud)
在这个方法中我想列出
我习惯了下面的代码,如何找到一个方法中调用的所有方法?
public class MethodFinder {
public static void main(String[] args) throws Throwable {
ClassPool cp = ClassPool.getDefault();
CtClass ctClass = cp.get("MyClass");
CtMethod method = ctClass.getDeclaredMethod("getItem1");
method.instrument(
new ExprEditor() {
public void edit(MethodCall m)
throws CannotCompileException
{
System.out.println(m.getClassName() + "." + m.getMethodName() + " " + m.getSignature());
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
并获取除 String::valueOf 之外的所有方法
是否可以通过任何其他框架解决这个问题并不重要。
由于String.valueOf实际上不是由方法调用的,因此 I\xe2\x80\x99d 使用更广泛的术语,例如谈论包含调用方法的引用方法。使用ASM ( java-bytecode-asm )收集所有这些信息的一种方法是:
import java.io.IOException;\nimport java.util.Optional;\nimport org.objectweb.asm.*;\n\npublic class FindAllReferencedMethods {\n class Example {\n void create() {\n System.out.println("TEST");\n Optional.of("String").map(String::valueOf).get();\n }\n }\n public static void main(String[] args) throws IOException {\n ClassReader r = new ClassReader(Example.class.getName());\n r.accept(new ClassVisitor(Opcodes.ASM5) {\n @Override\n public MethodVisitor visitMethod(\n int access, String name, String desc, String sig, String[] ex) {\n return name.equals("create")? new MethodRefCollector(): null;\n }\n\n }, ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES);\n }\n\n static void referencedMethod(String owner, String name, String desc) {\n System.out.println(\n Type.getObjectType(owner).getClassName() + "." + name + " " + desc);\n }\n\n static class MethodRefCollector extends MethodVisitor {\n public MethodRefCollector() {\n super(Opcodes.ASM5);\n }\n\n @Override\n public void visitMethodInsn(\n int opcode, String owner, String name, String desc, boolean itf) {\n referencedMethod(owner, name, desc);\n }\n\n @Override\n public void visitInvokeDynamicInsn(\n String name, String desc, Handle bsm, Object... bsmArgs) {\n if(bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory")\n && bsm.getDesc().equals(bsm.getName().equals("altMetafactory")?\n ALT_SIG: MF_SIG)) {\n Handle target = (Handle)bsmArgs[1];\n referencedMethod(target.getOwner(), target.getName(), target.getDesc());\n }\n }\n }\n static String MF_SIG = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;"\n +"Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/"\n +"MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;";\n static String ALT_SIG = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;"\n +"Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;";\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1033 次 |
| 最近记录: |