简体   繁体   English

如何使用 Java 列出文件中所有导入类的所有方法?

[英]How can I list all methods of all imported classes in a file using Java?

My objective is to look at some lines of codes of an external file and count the number of functions of a class are called then.我的目标是查看外部文件的一些代码行,然后计算调用 class 的函数数。

For example, if I have the following code:例如,如果我有以下代码:

import java.io.BufferedReader;
import whatever.MyClass;
import java.util.ArrayList;
...
...
public void example(){
    InputStreamReader isr = new InputStreamReader (whatever);
    MyClass object = new MyClass();
    someArrayList.add(whatever2)
    someArrayList.add(whatever3)
}

In this case, BufferedReader and MyClass functions were called once, and ArrayList functions were called twice.本例中BufferedReaderMyClass函数被调用了一次, ArrayList函数被调用了两次。

My solution for that is get a list of all methods inside the used classes and try to match with some string of my code.我的解决方案是获取所用类中所有方法的列表,并尝试与我的代码中的一些字符串匹配。 For classes created in my project, I can do the following:对于在我的项目中创建的类,我可以执行以下操作:

jar -tf jarPath

which returns me the list of classes inside a JAR. And doing:这会返回 JAR 中的类列表。并执行以下操作:

javap -cp jarPath className

I can get a list of all methods inside a JAR whit a specific class name.我可以获得 JAR 内所有方法的列表,并带有特定的 class 名称。 However, what can I do to get a external methods names, like add(...) of an "external" class java.util.ArrayList ?但是,我该怎么做才能获得外部方法名称,例如“外部” class java.util.ArrayListadd(...) I can't access the .jar file of java.util.ArrayList correct?我无法访问 java.util.ArrayList 的.jar文件, java.util.ArrayList吗? Anyone have another suggestion to reach the objective?有人有其他建议来达到目标吗?

The compiler doesn't put the imports into the object file.编译器不会将导入放入 object 文件中。 It throws them away.它把它们扔掉了。 Import is just a shorthand to the compiler.(Imports are a compile-time feature ). Import 只是编译器的简写。(Imports 是一个编译时特性)。

first step:第一步:

use Qdox https://github.com/paul-hammant/qdox to get all the imports in a class:使用 Qdox https://github.com/paul-hammant/qdox获取 class 中的所有导入:

String fileFullPath = "Your\\java\\ file \\full\\path";
JavaDocBuilder builder = new JavaDocBuilder();
builder.addSource(new FileReader( fileFullPath  ));

JavaSource src = builder.getSources()[0];
String[] imports = src.getImports();

for ( String imp : imports )
{
    System.out.println(imp);
}

second step: inspire from that code, loop through your imports (String array) and apply the same code and you will get the methods.第二步:从该代码中获得灵感,循环导入(字符串数组)并应用相同的代码,您将获得这些方法。

 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;

  public class Tes {
  public static void main(String[] args) {
    Class c;
    try {
        c = Class.forName("java.util.ArrayList");
        Arrays.stream(getAccessibleMethods(c)).
                              forEach(System.out::println);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

public static Method[] getAccessibleMethods(Class clazz) {
    List<Method> result = new ArrayList<Method>();
    while (clazz != null) {
        for (Method method : clazz.getDeclaredMethods()) {
            result.add(method);
        }
        clazz = clazz.getSuperclass();
    }
    return result.toArray(new Method[result.size()]);
}
}

Output: Output:

  public void java.util.ArrayList.add(int,java.lang.Object)
  public boolean java.util.ArrayList.add(java.lang.Object)
  public boolean java.util.ArrayList.remove(java.lang.Object)
  public java.lang.Object java.util.ArrayList.remove(int)
  public java.lang.Object java.util.ArrayList.get(int)
  public java.lang.Object java.util.ArrayList.clone()
  public int java.util.ArrayList.indexOf(java.lang.Object)
  public void java.util.ArrayList.clear()
  .
  .
  .

All the code - one class:所有代码 - 一个 class:

  import java.io.FileNotFoundException;
  import java.io.FileReader;
  import java.lang.reflect.Method;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;

  import com.thoughtworks.qdox.JavaDocBuilder;
  import com.thoughtworks.qdox.model.JavaSource;

  public class Tester {
  public static void main(String[] args) {
  // put your .java file path
  // CyclicB is a class within another project in my pc
    String fileFullPath =
      "C:\\Users\\OUSSEMA\\Desktop\\dev\\OCP_Preparation\\src\\w\\CyclicB.java";
JavaDocBuilder builder = new JavaDocBuilder();
try {
    builder.addSource(new FileReader( fileFullPath  ));
} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

JavaSource src = builder.getSources()[0];
String[] imports = src.getImports();

for ( String imp : imports )
{
    Class c;
    try {
        c = Class.forName(imp);
        Arrays.stream(getAccessibleMethods(c)).
                              forEach(System.out::println);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
 }
 }
  public static Method[] getAccessibleMethods(Class clazz) {
  List<Method> result = new ArrayList<Method>();
  while (clazz != null) {
    for (Method method : clazz.getDeclaredMethods()) {
        result.add(method);
    }
    clazz = clazz.getSuperclass();
  }
return result.toArray(new Method[result.size()]);
}
}

Output all the methods within the classes imported in the file CyclicB.java: Output 在文件 CyclicB.java 中导入的类中的所有方法:

  private void java.lang.Throwable.printStackTrace(java.lang.Throwable$PrintStreamOrWriter)
  public void java.lang.Throwable.printStackTrace(java.io.PrintStream)
  public void java.lang.Throwable.printStackTrace()
  public void java.lang.Throwable.printStackTrace(java.io.PrintWriter)
  public synchronized java.lang.Throwable java.lang.Throwable.fillInStackTrace()
  .
  .
  .

You may look into OpenJDK project that has a Java compiler.您可以查看具有 Java 编译器的OpenJDK项目。 Learn to build the modified versions.学习构建修改后的版本。 Investigate the syntax analysis layer of this compiler and find where the method calls are handled.调查此编译器的语法分析层并找到处理方法调用的位置。 Put the logging into these locations and now you only need to build your java file with the modified compiler to get the information about the calls.将日志记录放入这些位置,现在您只需使用修改后的编译器构建 java 文件即可获取有关调用的信息。

The build is complex, but you will likely only need a careful editing in a few files.构建很复杂,但您可能只需要仔细编辑几个文件。 It is not exactly very low hanging fruit but I think it should be possible to discover these files and make changes in them, and still may be a simpler/cleaner approach than to implement the own Java syntax parser (also doable with JavaCC ).这并不是很容易实现的目标,但我认为应该可以发现这些文件并对其进行更改,并且仍然可能是比实现自己的 Java 语法解析器(也可以使用JavaCC )更简单/更干净的方法。

If you also need to track calls from the external libraries, build them with the modified compiler as well and you will have the needed records.如果您还需要跟踪来自外部库的调用,也可以使用修改后的编译器构建它们,您将获得所需的记录。

GNU Classpath is another open source project where you can do the similar thing, and it may be easier to build. GNU Classpath是另一个开源项目,您可以在其中做类似的事情,而且构建起来可能更容易。 However, unlike OpenJDK, GNU Classpath java system library is not complete.但是,与 OpenJDK 不同的是,GNU Classpath java 系统库并不完整。

This approach may not discover some methods called during reflection.这种方法可能不会发现一些在反射期间调用的方法。 But it would discover that reflection framework methods have been called.但是它会发现调用了反射框架方法。 If it is a security - related project, the simplest would be to agree that reflection is not allowed.如果是安全相关的项目,最简单的就是同意不允许反射。 It is uncommon to use reflection in a normal Java application that is not a framework.在不是框架的普通 Java 应用程序中使用反射是不常见的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 java使用cmd列出特定包的jar文件中的所有方法和类 - java list all methods and classes in a jar file of specific package using cmd 所有Java标准类和方法的简单列表? - Simple List of All Java Standard Classes and Methods? 如何获取eclipse中Java项目中使用的所有类和方法的列表? - How do I get the list of all the classes and methods used in a Java project in eclipse? 如何列出源代码中使用的 Android SDK 中的所有类和方法? - How can I list all classes and methods from Android SDK used in my source code? 在哪里可以找到所有Java(SE 7)标准库类的列表,这些类具有的方法将引发EOFException? - Where can I find the list of all Java (SE 7) standard library classes which have methods which will throw an EOFException? 使用Java,如何列出和打印MS-Access 2003 mdb文件中的所有查询? - Using Java, How can I list and print all Queries in a MS-Access 2003 mdb file? Eclipse - 使用其方法列出所有类 - Eclipse - List all the classes with their methods 如何枚举包中的所有类并将它们添加到List? - How can I enumerate all classes in a package and add them to a List? 如何列出特定类加载器中加载的所有类 - How can I list all classes loaded in a specific class loader 如何在一个类中循环所有方法和对象? (Java)的 - How can I loop all methods and objects in a class? (java)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM