解析方法调用:对其他类的隐式依赖

时间:2015-11-10 07:41:15

标签: java parsing methods

我正在尝试解析java源代码文件中的所有方法调用,并将它们与各自的类相关联。首先,我认为我只需要查找通过import语句导入的类(我们的公司指南禁止* -imports)。然后我可以找出这种类型的变量在哪里使用并记录他们的方法调用。

然后我注意到有像

这样的结构
A.getB().getC()

B类实际上从未被导入(因为它没有被显式使用),但它的函数getC()被调用(并且源代码以某种方式隐含地"取决于它#34;)。

还有其他此类案件吗?

4 个答案:

答案 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)

不是您正在寻找的确切答案,但您可能最好通过现有库构建类的抽象语法树(或类似),而不是尝试自己解析源代码。

然后你就能看到你的确切内容。

以下是一个例子:

http://spoon.gforge.inria.fr/

还有其他一些人; 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使用导入的类,比如:

  • //方法B.getC :()LC; - &GT;使用了B类
  • //方法C.getD :()LD; - &GT;使用了C类

但我认为最好的方法是使用Abstract Syntax Tree作为@Kong,