2017-11-02 37 views
0

메서드에서 호출하는 모든 메서드를 나열하고 싶습니다. 이 방법에서는Lamda를 포함한 메소드에서 호출 된 모든 메소드를 찾는 방법은 무엇입니까?

void create() throws MyException { 
    System.out.println("TEST"); 
    of("String").map(String::valueOf).get(); 
} 

내가

  • 지도
  • 문자열 :: valueOf
  • 의 get()

    • 에서 System.out.println을 나열하고 싶습니다;

    나는 how to find all methods called in a method?

    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()); 
          } 
         }); 
        } 
    } 
    

    에서, 다음 코드로 사용이가 다른 프레임 워크에 의해 해결되는 경우가 문제 dosn't 문자열 :: valueOf

    를 제외한 모든 방법을 얻을 수있다.

  • +2

    주 그것을 map 메소드에 전달합니다. 엄밀히 말하자면, 메소드는 전달 메소드가 실제로 호출되는지 여부를 알지 못합니다. – luk2302

    +0

    알아낼 수있는 방법은 무엇입니까 :)? – Trind

    +0

    그리고 전달 된 메소드에 대한 참조 만 필요합니다. – Trind

    답변

    3

    String.valueOf은 메소드에서 실제로 호출되지 않으므로보다 광범위한 용어를 사용합니다. 참조 된 메소드에 대해 이야기하십시오. 여기에는 호출 된 메소드가 포함됩니다. ASM ()를 사용하여 그들 모두를 수집하는 한 가지 방법은 다음과 같습니다 당신의 방법은`create`는 방법`String.valueOf`를 호출하지,하지만 방법에 대한 참조를 가져옵니다에만 않기 때문에이 올바른지

    import java.io.IOException; 
    import java.util.Optional; 
    import org.objectweb.asm.*; 
    
    public class FindAllReferencedMethods { 
        class Example { 
         void create() { 
          System.out.println("TEST"); 
          Optional.of("String").map(String::valueOf).get(); 
         } 
        } 
        public static void main(String[] args) throws IOException { 
         ClassReader r = new ClassReader(Example.class.getName()); 
         r.accept(new ClassVisitor(Opcodes.ASM5) { 
          @Override 
          public MethodVisitor visitMethod(
            int access, String name, String desc, String sig, String[] ex) { 
           return name.equals("create")? new MethodRefCollector(): null; 
          } 
    
         }, ClassReader.SKIP_DEBUG|ClassReader.SKIP_FRAMES); 
        } 
    
        static void referencedMethod(String owner, String name, String desc) { 
         System.out.println(
          Type.getObjectType(owner).getClassName() + "." + name + " " + desc); 
        } 
    
        static class MethodRefCollector extends MethodVisitor { 
         public MethodRefCollector() { 
          super(Opcodes.ASM5); 
         } 
    
         @Override 
         public void visitMethodInsn(
            int opcode, String owner, String name, String desc, boolean itf) { 
          referencedMethod(owner, name, desc); 
         } 
    
         @Override 
         public void visitInvokeDynamicInsn(
            String name, String desc, Handle bsm, Object... bsmArgs) { 
          if(bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory") 
          && bsm.getDesc().equals(bsm.getName().equals("altMetafactory")? 
                ALT_SIG: MF_SIG)) { 
           Handle target = (Handle)bsmArgs[1]; 
           referencedMethod(target.getOwner(), target.getName(), target.getDesc()); 
          } 
         } 
        } 
        static String MF_SIG = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;" 
         +"Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/" 
         +"MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"; 
        static String ALT_SIG = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;" 
         +"Ljava/lang/invoke/MethodType;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;"; 
    }