如何在Java中找到调用给定方法的所有方法?

时间:2021-09-12 17:19:26

I need to get a list of all caller methods for a method of interest for me in Java. Is there a tool that can help me with this?

我需要获取Java中感兴趣的方法的所有调用方法的列表。有没有可以帮助我的工具?

Edit: I forgot to mention that I need to do this from a program. I'm usig Java Pathfinder and I want to run it an all the methods that call my method of interest.

编辑:我忘了提到我需要从程序中执行此操作。我使用Java Pathfinder,我想运行它调用我感兴趣的方法的所有方法。

11 个解决方案

#1


40  

For analyzing bytecode, I would recommend ASM. Given a list of Classes to analyze, a visitor can be made which finds the method calls you're interested in. One implementation which analyses classes in a jar file is below.

为了分析字节码,我建议使用ASM。给定要分析的类列表,可以创建一个查找您感兴趣的方法调用的访问者。下面是一个分析jar文件中的类的实现。

Note that ASM uses internalNames with '/' instead of '.' as a separator. Specify the target method as a standard declaration without modifiers.

请注意,ASM使用带有'/'的internalNames而不是'。'作为分隔符。将目标方法指定为不带修饰符的标准声明。

For example, to list methods that could be calling System.out.println("foo") in the java runtime jar:

例如,要列出可以在java运行时jar中调用System.out.println(“foo”)的方法:

java -cp "classes;asm-3.1.jar;asm-commons-3.1.jar" App \
    c:/java/jdk/jre/lib/rt.jar \
    java/io/PrintStream  "void println(String)"

Edit: source and line numbers added: Note that this only indicates the last target method invocation per calling method - the original q only wanted to know which methods. I leave it as an exercise for the reader to show line numbers of the calling method declaration, or the line numbers of every target invocation, depending on what you're actually after. :)

编辑:添加源和行号:请注意,这仅表示每个调用方法的最后一个目标方法调用 - 原始q只想知道哪些方法。我把它作为练习让读者显示调用方法声明的行号,或每个目标调用的行号,具体取决于你实际使用的内容。 :)

results in:

LogSupport.java:44 com/sun/activation/registries/LogSupport log (Ljava/lang/String;)V
LogSupport.java:50 com/sun/activation/registries/LogSupport log (Ljava/lang/String;Ljava/lang/Throwable;)V
...
Throwable.java:498 java/lang/Throwable printStackTraceAsCause (Ljava/io/PrintStream;[Ljava/lang/StackTraceElement;)V
--
885 methods invoke java/io/PrintStream println (Ljava/lang/String;)V

source:

public class App {
    private String targetClass;
    private Method targetMethod;

    private AppClassVisitor cv;

    private ArrayList<Callee> callees = new ArrayList<Callee>();

    private static class Callee {
        String className;
        String methodName;
        String methodDesc;
        String source;
        int line;

        public Callee(String cName, String mName, String mDesc, String src, int ln) {
            className = cName; methodName = mName; methodDesc = mDesc; source = src; line = ln;
        }
    }

    private class AppMethodVisitor extends MethodAdapter {

        boolean callsTarget;
        int line;

        public AppMethodVisitor() { super(new EmptyVisitor()); }

        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
            if (owner.equals(targetClass)
                    && name.equals(targetMethod.getName())
                    && desc.equals(targetMethod.getDescriptor())) {
                callsTarget = true;
            }
        }

        public void visitCode() {
            callsTarget = false;
        }

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

        public void visitEnd() {
            if (callsTarget)
                callees.add(new Callee(cv.className, cv.methodName, cv.methodDesc, 
                        cv.source, line));
        }
    }

    private class AppClassVisitor extends ClassAdapter {

        private AppMethodVisitor mv = new AppMethodVisitor();

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

        public AppClassVisitor() { super(new EmptyVisitor()); }

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

        public void visitSource(String source, String debug) {
            this.source = source;
        }

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

            return mv;
        }
    }


    public void findCallingMethodsInJar(String jarPath, String targetClass,
                                        String targetMethodDeclaration) throws Exception {

        this.targetClass = targetClass;
        this.targetMethod = Method.getMethod(targetMethodDeclaration);

        this.cv = new AppClassVisitor();

        JarFile jarFile = new JarFile(jarPath);
        Enumeration<JarEntry> entries = jarFile.entries();

        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();

            if (entry.getName().endsWith(".class")) {
                InputStream stream = new BufferedInputStream(jarFile.getInputStream(entry), 1024);
                ClassReader reader = new ClassReader(stream);

                reader.accept(cv, 0);

                stream.close();
            }
        }
    }


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

            app.findCallingMethodsInJar(args[0], args[1], args[2]);

            for (Callee c : app.callees) {
                System.out.println(c.source+":"+c.line+" "+c.className+" "+c.methodName+" "+c.methodDesc);
            }

            System.out.println("--\n"+app.callees.size()+" methods invoke "+
                    app.targetClass+" "+
                    app.targetMethod.getName()+" "+app.targetMethod.getDescriptor());
        } catch(Exception x) {
            x.printStackTrace();
        }
    }

}

#2


12  

Edit: the original question was edited to indicate a runtime solution was needed - this answer was given before that edit and only indicates how to do it during development.

编辑:编辑原始问题以指示需要运行时解决方案 - 在编辑之前给出了此答案,并且仅指示在开发期间如何执行此操作。

If you are using Eclipse you can right click the method and choose "Open call hierarchy" to get this information.

如果您使用的是Eclipse,则可以右键单击该方法并选择“打开调用层次结构”以获取此信息。

Updated after reading comments: Other IDEs support this as well in a similar fashion (at least Netbeans and IntelliJ do)

阅读评论后更新:其他IDE也以类似的方式支持这一点(至少Netbeans和IntelliJ做)

#3


5  

Annotate the method with @Deprecated ( or tag it with @deprecated ), turn on deprecation warnings, run your compile and see which warnings get triggered.

使用@Deprecated注释方法(或使用@deprecated标记),打开弃用警告,运行编译并查看触发的警告。

The run your compile bit can be done either by invoking an external ant process or by using the Java 6 compiler API.

运行编译位可以通过调用外部ant进程或使用Java 6编译器API来完成。

#4


5  

  1. right click on method
  2. 右键单击方法

  3. Go to references and (depending on your requirement)
    choose workspace/project/Hierarchy.
  4. 转到参考和(根据您的要求)选择工作区/项目/层次结构。

This pops up a panel that shows all references to this functions. Eclipse FTW !

这会弹出一个面板,显示对此功能的所有引用。 Eclipse FTW!

#5


3  

There isn't a way to do this (programmatically) via the Java reflection libraries - you can't ask a java.lang.reflect.Method "which methods do you call?"

没有办法通过Java反射库(以编程方式)执行此操作 - 您不能要求java.lang.reflect.Method“您调用哪些方法?”

That leaves two other options I can think of:

这留下了我能想到的另外两个选择:

  1. Static analysis of the source code. I'm sure this is what the Eclipse Java toolset does - you could look at the Eclipse source behind the JDT, and find what it does when you ask Eclipse to "Find References" to a method.

    静态分析源代码。我确信这就是Eclipse Java工具集所做的事情 - 您可以查看JDT背后的Eclipse源代码,并在您向Eclipse请求方法的“查找引用”时查找它的作用。

  2. Bytecode analysis. You could inspect the bytecode for calls to the method. I'm not sure what libraries or examples are out there to help with this - but I can't imagine that something doesn't exist.

    字节码分析。您可以检查字节码以获取对方法的调用。我不确定哪些库或示例可以帮助解决这个问题 - 但我无法想象某些东西不存在。

#6


3  

In eclipse, highlight the method name and then Ctrl+Shift+G

在eclipse中,突出显示方法名称,然后按Ctrl + Shift + G

#7


1  

Yes, most modern IDE:s will let you either search for usages of a method or variable. Alternatively, you could use a debugger and set a trace point on the method entry, printing a stack trace or whatever every time the method is invoked. Finally, you could use some simple shell util to just grep for the method, such as

是的,大多数现代IDE:s将允许您搜索方法或变量的用法。或者,您可以使用调试器并在方法条目上设置跟踪点,在每次调用方法时打印堆栈跟踪或其他任何内容。最后,您可以使用一些简单的shell util来为该方法设置grep,例如

find . -name '*.java' -exec grep -H methodName {} ;

The only method that will let you find invokations made through some reflection method, though, would be using the debugger.

但是,唯一可以通过某种反射方法查找调用的方法是使用调试器。

#8


1  

1)In eclipse it is ->right click on the method and select open call hierarchy or CLT+ALT+H

1)在eclipse中,它是 - >右键单击该方法并选择打开调用层次结构或CLT + ALT + H.

2)In jdeveloper it is -> right click on the method and select calls or ALT+SHIFT+H

2)在jdeveloper中,它是 - >右键单击方法并选择调用或ALT + SHIFT + H.

#9


0  

The closest that I could find was the method described in this * questions selected answer.check this out

我能找到的最接近的是此*中描述的方法问题选择了答案。检查出来

#10


0  

I made a small example using @Chadwick's one. It's a test that assesses if calls to getDatabaseEngine() are made by methods that implement @Transaction.

我用@ Chadwick的一个做了一个小例子。这是一个测试,评估是否通过实现@Transaction的方法调用getDatabaseEngine()。

/**
 * Ensures that methods that call {@link DatabaseProvider#getDatabaseEngine()}
 * implement the {@link @Transaction} annotation.
 *
 * @throws Exception If something occurs while testing.
 */
@Test
public void ensure() throws Exception {
    final Method method = Method.getMethod(
            DatabaseEngine.class.getCanonicalName() + " getDatabaseEngine()");

    final ArrayList<java.lang.reflect.Method> faultyMethods = Lists.newArrayList();

    for (Path p : getAllClasses()) {
        try (InputStream stream = new BufferedInputStream(Files.newInputStream(p))) {
            ClassReader reader = new ClassReader(stream);


            reader.accept(new ClassAdapter(new EmptyVisitor()) {
                @Override
                public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {

                    return new MethodAdapter(new EmptyVisitor()) {
                        @Override
                        public void visitMethodInsn(int opcode, String owner, String nameCode, String descCode) {
                            try {
                                final Class<?> klass = Class.forName(Type.getObjectType(owner).getClassName());
                                if (DatabaseProvider.class.isAssignableFrom(klass) &&
                                        nameCode.equals(method.getName()) &&
                                        descCode.equals(method.getDescriptor())) {

                                    final java.lang.reflect.Method method = klass.getDeclaredMethod(name,
                                            getParameters(desc).toArray(new Class[]{}));

                                    for (Annotation annotation : method.getDeclaredAnnotations()) {
                                        if (annotation.annotationType().equals(Transaction.class)) {
                                            return;
                                        }
                                    }

                                    faultyMethods.add(method);

                                }
                            } catch (Exception e) {
                                Throwables.propagate(e);
                            }
                        }
                    };
                }
            }, 0);

        }
    }

    if (!faultyMethods.isEmpty()) {
        fail("\n\nThe following methods must implement @Transaction because they're calling getDatabaseEngine().\n\n" + Joiner.on("\n").join
                (faultyMethods) + "\n\n");
    }

}

/**
 * Gets all the classes from target.
 *
 * @return The list of classes.
 * @throws IOException If something occurs while collecting those classes.
 */
private List<Path> getAllClasses() throws IOException {
    final ImmutableList.Builder<Path> builder = new ImmutableList.Builder<>();
    Files.walkFileTree(Paths.get("target", "classes"), new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
            if (file.getFileName().toString().endsWith(".class")) {
                builder.add(file);
            }
            return FileVisitResult.CONTINUE;
        }
    });

    return builder.build();
}

/**
 * Gets the list of parameters given the description.
 *
 * @param desc The method description.
 * @return The list of parameters.
 * @throws Exception If something occurs getting the parameters.
 */
private List<Class<?>> getParameters(String desc) throws Exception {
    ImmutableList.Builder<Class<?>> obj = new ImmutableList.Builder<>();

    for (Type type : Type.getArgumentTypes(desc)) {
        obj.add(ClassUtils.getClass(type.getClassName()));
    }

    return obj.build();
}

#11


-1  

You can do this with something in your IDE such as "Find Usages" (which is what it is called in Netbeans and JDeveloper). A couple of things to note:

您可以使用IDE中的某些内容执行此操作,例如“查找用法”(这是Netbeans和JDeveloper中所称的内容)。有几点需要注意:

  1. If your method implements a method from an interface or base class, you can only know that your method is POSSIBLY called.
  2. 如果您的方法从接口或基类实现方法,则只能知道您的方法是可能被调用的。

  3. A lot of Java frameworks use Reflection to call your method (IE Spring, Hibernate, JSF, etc), so be careful of that.
  4. 很多Java框架使用Reflection来调用你的方法(IE Spring,Hibernate,JSF等),所以要小心。

  5. On the same note, your method could be called by some framework, reflectively or not, so again be careful.
  6. 在同一个注释中,您的方法可以由某个框架调用,反射或不反映,所以再次要小心。

#1


40  

For analyzing bytecode, I would recommend ASM. Given a list of Classes to analyze, a visitor can be made which finds the method calls you're interested in. One implementation which analyses classes in a jar file is below.

为了分析字节码,我建议使用ASM。给定要分析的类列表,可以创建一个查找您感兴趣的方法调用的访问者。下面是一个分析jar文件中的类的实现。

Note that ASM uses internalNames with '/' instead of '.' as a separator. Specify the target method as a standard declaration without modifiers.

请注意,ASM使用带有'/'的internalNames而不是'。'作为分隔符。将目标方法指定为不带修饰符的标准声明。

For example, to list methods that could be calling System.out.println("foo") in the java runtime jar:

例如,要列出可以在java运行时jar中调用System.out.println(“foo”)的方法:

java -cp "classes;asm-3.1.jar;asm-commons-3.1.jar" App \
    c:/java/jdk/jre/lib/rt.jar \
    java/io/PrintStream  "void println(String)"

Edit: source and line numbers added: Note that this only indicates the last target method invocation per calling method - the original q only wanted to know which methods. I leave it as an exercise for the reader to show line numbers of the calling method declaration, or the line numbers of every target invocation, depending on what you're actually after. :)

编辑:添加源和行号:请注意,这仅表示每个调用方法的最后一个目标方法调用 - 原始q只想知道哪些方法。我把它作为练习让读者显示调用方法声明的行号,或每个目标调用的行号,具体取决于你实际使用的内容。 :)

results in:

LogSupport.java:44 com/sun/activation/registries/LogSupport log (Ljava/lang/String;)V
LogSupport.java:50 com/sun/activation/registries/LogSupport log (Ljava/lang/String;Ljava/lang/Throwable;)V
...
Throwable.java:498 java/lang/Throwable printStackTraceAsCause (Ljava/io/PrintStream;[Ljava/lang/StackTraceElement;)V
--
885 methods invoke java/io/PrintStream println (Ljava/lang/String;)V

source:

public class App {
    private String targetClass;
    private Method targetMethod;

    private AppClassVisitor cv;

    private ArrayList<Callee> callees = new ArrayList<Callee>();

    private static class Callee {
        String className;
        String methodName;
        String methodDesc;
        String source;
        int line;

        public Callee(String cName, String mName, String mDesc, String src, int ln) {
            className = cName; methodName = mName; methodDesc = mDesc; source = src; line = ln;
        }
    }

    private class AppMethodVisitor extends MethodAdapter {

        boolean callsTarget;
        int line;

        public AppMethodVisitor() { super(new EmptyVisitor()); }

        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
            if (owner.equals(targetClass)
                    && name.equals(targetMethod.getName())
                    && desc.equals(targetMethod.getDescriptor())) {
                callsTarget = true;
            }
        }

        public void visitCode() {
            callsTarget = false;
        }

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

        public void visitEnd() {
            if (callsTarget)
                callees.add(new Callee(cv.className, cv.methodName, cv.methodDesc, 
                        cv.source, line));
        }
    }

    private class AppClassVisitor extends ClassAdapter {

        private AppMethodVisitor mv = new AppMethodVisitor();

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

        public AppClassVisitor() { super(new EmptyVisitor()); }

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

        public void visitSource(String source, String debug) {
            this.source = source;
        }

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

            return mv;
        }
    }


    public void findCallingMethodsInJar(String jarPath, String targetClass,
                                        String targetMethodDeclaration) throws Exception {

        this.targetClass = targetClass;
        this.targetMethod = Method.getMethod(targetMethodDeclaration);

        this.cv = new AppClassVisitor();

        JarFile jarFile = new JarFile(jarPath);
        Enumeration<JarEntry> entries = jarFile.entries();

        while (entries.hasMoreElements()) {
            JarEntry entry = entries.nextElement();

            if (entry.getName().endsWith(".class")) {
                InputStream stream = new BufferedInputStream(jarFile.getInputStream(entry), 1024);
                ClassReader reader = new ClassReader(stream);

                reader.accept(cv, 0);

                stream.close();
            }
        }
    }


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

            app.findCallingMethodsInJar(args[0], args[1], args[2]);

            for (Callee c : app.callees) {
                System.out.println(c.source+":"+c.line+" "+c.className+" "+c.methodName+" "+c.methodDesc);
            }

            System.out.println("--\n"+app.callees.size()+" methods invoke "+
                    app.targetClass+" "+
                    app.targetMethod.getName()+" "+app.targetMethod.getDescriptor());
        } catch(Exception x) {
            x.printStackTrace();
        }
    }

}

#2


12  

Edit: the original question was edited to indicate a runtime solution was needed - this answer was given before that edit and only indicates how to do it during development.

编辑:编辑原始问题以指示需要运行时解决方案 - 在编辑之前给出了此答案,并且仅指示在开发期间如何执行此操作。

If you are using Eclipse you can right click the method and choose "Open call hierarchy" to get this information.

如果您使用的是Eclipse,则可以右键单击该方法并选择“打开调用层次结构”以获取此信息。

Updated after reading comments: Other IDEs support this as well in a similar fashion (at least Netbeans and IntelliJ do)

阅读评论后更新:其他IDE也以类似的方式支持这一点(至少Netbeans和IntelliJ做)

#3


5  

Annotate the method with @Deprecated ( or tag it with @deprecated ), turn on deprecation warnings, run your compile and see which warnings get triggered.

使用@Deprecated注释方法(或使用@deprecated标记),打开弃用警告,运行编译并查看触发的警告。

The run your compile bit can be done either by invoking an external ant process or by using the Java 6 compiler API.

运行编译位可以通过调用外部ant进程或使用Java 6编译器API来完成。

#4


5  

  1. right click on method
  2. 右键单击方法

  3. Go to references and (depending on your requirement)
    choose workspace/project/Hierarchy.
  4. 转到参考和(根据您的要求)选择工作区/项目/层次结构。

This pops up a panel that shows all references to this functions. Eclipse FTW !

这会弹出一个面板,显示对此功能的所有引用。 Eclipse FTW!

#5


3  

There isn't a way to do this (programmatically) via the Java reflection libraries - you can't ask a java.lang.reflect.Method "which methods do you call?"

没有办法通过Java反射库(以编程方式)执行此操作 - 您不能要求java.lang.reflect.Method“您调用哪些方法?”

That leaves two other options I can think of:

这留下了我能想到的另外两个选择:

  1. Static analysis of the source code. I'm sure this is what the Eclipse Java toolset does - you could look at the Eclipse source behind the JDT, and find what it does when you ask Eclipse to "Find References" to a method.

    静态分析源代码。我确信这就是Eclipse Java工具集所做的事情 - 您可以查看JDT背后的Eclipse源代码,并在您向Eclipse请求方法的“查找引用”时查找它的作用。

  2. Bytecode analysis. You could inspect the bytecode for calls to the method. I'm not sure what libraries or examples are out there to help with this - but I can't imagine that something doesn't exist.

    字节码分析。您可以检查字节码以获取对方法的调用。我不确定哪些库或示例可以帮助解决这个问题 - 但我无法想象某些东西不存在。

#6


3  

In eclipse, highlight the method name and then Ctrl+Shift+G

在eclipse中,突出显示方法名称,然后按Ctrl + Shift + G

#7


1  

Yes, most modern IDE:s will let you either search for usages of a method or variable. Alternatively, you could use a debugger and set a trace point on the method entry, printing a stack trace or whatever every time the method is invoked. Finally, you could use some simple shell util to just grep for the method, such as

是的,大多数现代IDE:s将允许您搜索方法或变量的用法。或者,您可以使用调试器并在方法条目上设置跟踪点,在每次调用方法时打印堆栈跟踪或其他任何内容。最后,您可以使用一些简单的shell util来为该方法设置grep,例如

find . -name '*.java' -exec grep -H methodName {} ;

The only method that will let you find invokations made through some reflection method, though, would be using the debugger.

但是,唯一可以通过某种反射方法查找调用的方法是使用调试器。

#8


1  

1)In eclipse it is ->right click on the method and select open call hierarchy or CLT+ALT+H

1)在eclipse中,它是 - >右键单击该方法并选择打开调用层次结构或CLT + ALT + H.

2)In jdeveloper it is -> right click on the method and select calls or ALT+SHIFT+H

2)在jdeveloper中,它是 - >右键单击方法并选择调用或ALT + SHIFT + H.

#9


0  

The closest that I could find was the method described in this * questions selected answer.check this out

我能找到的最接近的是此*中描述的方法问题选择了答案。检查出来

#10


0  

I made a small example using @Chadwick's one. It's a test that assesses if calls to getDatabaseEngine() are made by methods that implement @Transaction.

我用@ Chadwick的一个做了一个小例子。这是一个测试,评估是否通过实现@Transaction的方法调用getDatabaseEngine()。

/**
 * Ensures that methods that call {@link DatabaseProvider#getDatabaseEngine()}
 * implement the {@link @Transaction} annotation.
 *
 * @throws Exception If something occurs while testing.
 */
@Test
public void ensure() throws Exception {
    final Method method = Method.getMethod(
            DatabaseEngine.class.getCanonicalName() + " getDatabaseEngine()");

    final ArrayList<java.lang.reflect.Method> faultyMethods = Lists.newArrayList();

    for (Path p : getAllClasses()) {
        try (InputStream stream = new BufferedInputStream(Files.newInputStream(p))) {
            ClassReader reader = new ClassReader(stream);


            reader.accept(new ClassAdapter(new EmptyVisitor()) {
                @Override
                public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {

                    return new MethodAdapter(new EmptyVisitor()) {
                        @Override
                        public void visitMethodInsn(int opcode, String owner, String nameCode, String descCode) {
                            try {
                                final Class<?> klass = Class.forName(Type.getObjectType(owner).getClassName());
                                if (DatabaseProvider.class.isAssignableFrom(klass) &&
                                        nameCode.equals(method.getName()) &&
                                        descCode.equals(method.getDescriptor())) {

                                    final java.lang.reflect.Method method = klass.getDeclaredMethod(name,
                                            getParameters(desc).toArray(new Class[]{}));

                                    for (Annotation annotation : method.getDeclaredAnnotations()) {
                                        if (annotation.annotationType().equals(Transaction.class)) {
                                            return;
                                        }
                                    }

                                    faultyMethods.add(method);

                                }
                            } catch (Exception e) {
                                Throwables.propagate(e);
                            }
                        }
                    };
                }
            }, 0);

        }
    }

    if (!faultyMethods.isEmpty()) {
        fail("\n\nThe following methods must implement @Transaction because they're calling getDatabaseEngine().\n\n" + Joiner.on("\n").join
                (faultyMethods) + "\n\n");
    }

}

/**
 * Gets all the classes from target.
 *
 * @return The list of classes.
 * @throws IOException If something occurs while collecting those classes.
 */
private List<Path> getAllClasses() throws IOException {
    final ImmutableList.Builder<Path> builder = new ImmutableList.Builder<>();
    Files.walkFileTree(Paths.get("target", "classes"), new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) throws IOException {
            if (file.getFileName().toString().endsWith(".class")) {
                builder.add(file);
            }
            return FileVisitResult.CONTINUE;
        }
    });

    return builder.build();
}

/**
 * Gets the list of parameters given the description.
 *
 * @param desc The method description.
 * @return The list of parameters.
 * @throws Exception If something occurs getting the parameters.
 */
private List<Class<?>> getParameters(String desc) throws Exception {
    ImmutableList.Builder<Class<?>> obj = new ImmutableList.Builder<>();

    for (Type type : Type.getArgumentTypes(desc)) {
        obj.add(ClassUtils.getClass(type.getClassName()));
    }

    return obj.build();
}

#11


-1  

You can do this with something in your IDE such as "Find Usages" (which is what it is called in Netbeans and JDeveloper). A couple of things to note:

您可以使用IDE中的某些内容执行此操作,例如“查找用法”(这是Netbeans和JDeveloper中所称的内容)。有几点需要注意:

  1. If your method implements a method from an interface or base class, you can only know that your method is POSSIBLY called.
  2. 如果您的方法从接口或基类实现方法,则只能知道您的方法是可能被调用的。

  3. A lot of Java frameworks use Reflection to call your method (IE Spring, Hibernate, JSF, etc), so be careful of that.
  4. 很多Java框架使用Reflection来调用你的方法(IE Spring,Hibernate,JSF等),所以要小心。

  5. On the same note, your method could be called by some framework, reflectively or not, so again be careful.
  6. 在同一个注释中,您的方法可以由某个框架调用,反射或不反映,所以再次要小心。