我正在尝试解析java源代码文件中的所有方法调用,并将它们与各自的类相关联。首先,我认为我只需要查找通过import语句导入的类(我们的公司指南禁止* -imports)。然后我可以找出这种类型的变量在哪里使用并记录他们的方法调用。
然后我注意到有像
这样的结构A.getB().getC()
B类实际上从未被导入(因为它没有被显式使用),但它的函数getC()被调用(并且源代码以某种方式隐含地"取决于它#34;)。
还有其他此类案件吗?
答案 0 :(得分:2)
显然,同一个包中的类不会出现在import语句中。 (你可能已经意识到了,但以防万一。)
此外,使用反射,可能有很多方法可以使用未导入的类(请参阅Black Joker刚刚发布的答案)。
此外,您可以通过
直接在语句中完全限定类package.subpackage.Class
它们也没有导入。
答案 1 :(得分:1)
是的。您可以使用Class.forName(xxx)
在运行时加载B类。像这样:
//get Class object of B
Class classB = Class.forName("package.to.B");
//get Method object of C in class
Method methodC = classB.getMethod("C", parameterTypes of methodC);
//for static method:
methodC.invoke(null, args of methodC);
//create an instance of class B:
Object instanceOfB = classB.newInstance();
// invoke the method C on this instance
methodC.invoke(instanceOfB, args of methodC);
答案 2 :(得分:1)
不是您正在寻找的确切答案,但您可能最好通过现有库构建类的抽象语法树(或类似),而不是尝试自己解析源代码。
然后你就能看到你的确切内容。
以下是一个例子:
还有其他一些人; ANTLR,Eclipse ......
答案 3 :(得分:1)
您可能对javap
感兴趣我创建了A.java,B.java,C.java,D.java fiels:
public class A {
public static void main(String[] args) {
B b = new B();
b.getC().getD();
}
}
并编译这些类。
现在我们可以使用javap来解释A.class:
javap -c A
并获取字节码:
公共类A { public A(); 码: 0:aload_0 1:invokespecial#1 //方法java / lang / Object。"" :() 4:返回
public static void main(java.lang.String[]);
Code:
0: new #2 // class B
3: dup
4: invokespecial #3 // Method B."<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #4 // Method B.getC:()LC;
12: invokevirtual #5 // Method C.getD:()LD;
15: pop
16: return
}
现在你可以让A.class使用导入的类,比如:
但我认为最好的方法是使用Abstract Syntax Tree作为@Kong,