获取类引用的所有类

时间:2011-01-04 10:36:02

标签: java

假设我在运行时有一个java.lang.Class实例。

在运行时,无论如何都要查看c使用了哪些类?例如如果c.foo实例化B,则B被“使用”。如果c.foo调用静态方法G.bar(),则使用G.

注意:只是试图获得静态知道的类 - 我很好地错过了反射加载的类。

在python中,在modulefinder中找到了相同的功能: http://docs.python.org/library/modulefinder.html

7 个答案:

答案 0 :(得分:3)

可以使用反射查询方法体,构造函数和静态初始化器 之外的所有内容。您可以查看字段和方法签名并反映字段以获取字段值的实际类。

在方法中使用是非常具有挑战性的。您可以使用BCEL或类似的工具来分析类文件,并提取类文件中硬编码的所有类名。但是一旦你对接口进行编程,这将失败:

public List someMethod() {
  return SomeClass.getList();
}

类文件不知道someMethod返回的类的类型。并且没有查找表或中央注册表。 JVM将知道类型,查看类是否已加载,如果没有,则尝试加载它。它不必关心哪个类要求其他类,它不会记录此信息。仅仅因为不需要exectution而不需要垃圾收集。

答案 1 :(得分:2)

恕我直言,这是不可能的,因为其他引用的类可以使用反射进行实例化。或者可以使用依赖注入机制注入它们。

答案 2 :(得分:1)

可以动态加载某些类,使用getLoadedClasses()

答案 3 :(得分:1)

你可以尝试这个Java Dependency Resolver project这不仅可以找到项目中特定类的引用类和jar。

答案 4 :(得分:0)

您可能需要查看Heap functions available in the JVM Tool Interface,它允许您遍历堆并递归地跟踪对象引用。尽管如此,还是需要做很多工作。

答案 5 :(得分:0)

查看Maven Dependency Analyzer及其班级ASMDependencyAnalyzer

Set<String> referencedClasses = new ASMDependencyAnalyzer().analyze(new File("ClassName.class").toURI().toURL())

答案 6 :(得分:0)

一个人可以使用javap -v ClassFile.class并检查结果。 常量池包含所有使用的类和接口引用的VM名称,例如类或Methodref等 它是一个文件系统操作(创建例如临时文件,读取类和/或jar文件)并且性能不佳,但是可以使用相对简单的正则表达式来研究非功能方面的参考类。例如,您可以检查是否确实未使用不允许的类等。

Constant pool:
#1 = InterfaceMethodref #263.#264     // appointmentplanner/api/Time.asMinutes:()I
#2 = Methodref          #105.#265     // appointmentplanner/APDayPlan."<init>":(Ljava/time/LocalDate;II)V
#3 = Methodref          #115.#266     // java/lang/Object."<init>":()V
#4 = Fieldref           #105.#267     // appointmentplanner/APDayPlan.date:Ljava/time/LocalDate;
#5 = Class              #268          // appointmentplanner/LinearAllocator
#6 = Methodref          #5.#269       // appointmentplanner/LinearAllocator."<init>":(II)V
#7 = Fieldref           #105.#270     // appointmentplanner/APDayPlan.allocator:Lappointmentplanner/LinearAllocator;