2014-11-23 70 views

回答

1

我解決它通過操縱代碼,鏈接上有點

import java.io.InputStream; 

import org.objectweb.asm.*; 
import org.objectweb.asm.commons.*; 

public class App{ 
    public static void main(String[] args) { 
     try { 
      Test test = new Test(); 

       test.findCallers(); 
     }catch (Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 


class Test { 
    private String targetClass; 
    private Method targetMethod; 

    private AppClassVisitor cv; 

    class AppMethodVisitor extends MethodVisitor { 
     boolean callsTarget; 
     int line; 

     public AppMethodVisitor() { 
      super(Opcodes.ASM5); 
     } 

     public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { 
      if (owner.equals("Fibonacci") && name.equals("join") && desc.equals("()V")) { 
       callsTarget = true; 
       System.out.println("Function join called on " + this.line); 
      } 
      super.visitMethodInsn(opcode, owner, name, desc, itf); 
     } 

     public void visitCode() { 
      callsTarget = false; 
     } 

     public void visitLineNumber(int line, Label start) { 
      this.line = line; 
     } 

     public void visitEnd() { 
      if (callsTarget){ 
       System.out.println(cv.className + cv.methodName + cv.methodDesc + line); 
      } 
     } 
    } 

    class AppClassVisitor extends ClassVisitor { 
     private AppMethodVisitor mv = new AppMethodVisitor(); 

     public String className; 
     public String methodName; 
     public String methodDesc; 

     public AppClassVisitor() { 
      super(Opcodes.ASM5); 
     } 

     public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { 
      className = name; 
     } 

     public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { 
      methodName = name; 
      methodDesc = desc; 

      return mv; 
     } 
    } 

    public void findCallers() throws Exception { 
     InputStream stream = App.class.getResourceAsStream("Fibonacci.class"); 
     ClassReader reader = new ClassReader(stream); 
     cv = new AppClassVisitor(); 

     reader.accept(cv, 0); 

     stream.close(); 
    } 
} 

Fibonacci.java內容:

public class Fibonacci extends Thread{ 
    int n; 
    int result; 

    public Fibonacci(int n){ 
     this.n = n; 
    } 

    public void run(){ 
     if((n == 0) || (n == 1)){ 
      result = 1; 
     }else{ 
      Fibonacci f1 = new Fibonacci(n - 1); 
      Fibonacci f2 = new Fibonacci(n - 2); 

      f1.start(); 
      f2.start(); 

      try{ 
       f1.join(); 
       f2.join(); 
      }catch(InterruptedException e){ 
       e.printStackTrace(); 
      } 

      result = f1.getResult() + f2.getResult(); 
     } 
    } 

    public int getResult(){ 
     return result; 
    } 

    public static void main(String[] args) { 
     Fibonacci f1 = new Fibonacci(5); 
     f1.start(); 

     try{ 
      f1.join(); 
     }catch(InterruptedException e){ 
      e.printStackTrace(); 
     } 

     System.out.println("Answer is " + f1.getResult()); 
    } 
}