如何在 java 程序中识别对外部 类 和方法的声明和引用?

How can I identify declarations and references to external classes and methods within a java program?

假设我有两个包(package1,package2),每个包中有一个class(package1.A, package2.B)。我需要使用 java 程序识别从 package1.A 到 package2.B 的引用,反之亦然,还需要引用每个 class 中的任何方法。

代码应该是这样的:

package package1;
public class A{
    public  A(){
        Class<?> clazz = Class.forName("package2.B");
        Method mthd = clazz.getMethod("someMethod", Integer.TYPE);
}
    public static void main(String[] args) {
        new A(); 
    }

Class B 是这样的:

package package2;
    public class B {
        public B someMethod(int someParam) {
            return null;
        }
    }

我只需要一些关于我应该如何开始使用解析器来解决这个问题的指示。我必须牢记什么样的规则?我的问题的目标是确定依赖性。

我不打算 post 这是因为它不是很好,但由于已经过去了几天而且你没有得到很多回应,这里是根据你的评论的不同类型的答案:

I'm trying to find dependencies between the two classes and their various methods.

如果您只需要在您自己的应用程序(不是外部库)中查找依赖项和调用,请继续阅读。

考虑在每个方法中注入一两行代码(在编译时通过脚本轻松完成?),并记录此信息。例如,您可以使用 object.getClass().??? 的变体来查找有关当前方法的信息,包括其包 class 和方法名称。

例如这个直接输出信息到控制台:

StackTraceElement[] ste = Thread.currentThread().getStackTrace();
System.out.println("Called by: "+ste[ste.length - 2].getMethodName());
Object object = new Object(){};
System.out.println("Method details: "+ object.getClass().getPackage().getName() +" - "+ object.getClass().getName() +" - "+ object.getClass().getEnclosingMethod().getName());

对于插入这些行的每个方法,每次调用时都会在控制台上吐出类似这样的内容:

Called by: source
Method details: myPackage - myClass - myMethod

通过将上述内容放入几个 classes 中,对我的一个应用程序进行快速测试的一些真实结果:

Called by: getStackTrace
Method details: testdump - testdump.TestDump - main
Called by: pumpEvents
Method details: testdump - testdump.Rect - paintComponent
Called by: checkFileSize
Method details: update - update.FTP - checkFileSize
Called by: checkFileSize
Method details: update - update.FTP - download
Called by: pumpEvents
Method details: testdump - testdump.Rect - paintComponent
...

我们可以很容易地准确地看到被调用的两个不同的包,而且我们通常可以看到它是从哪里调用的,尽管您需要尝试 ste[ste.length - 2].getMethodName() 到 return 不同的包行取决于您要查看的堆栈跟踪有多远。显然,这应该只在调试模式下使用,它会产生很多垃圾,但根据您的应用程序的大小,检查输出结果应该是一件简单的事情,可以手动或通过制作一个短程序来构建一棵依赖关系树供您检查。


或者,您可以以类似的方式使用 Java 9 stack walking API: