假设我在运行时有一个java.lang.Class实例。
在运行时,无论如何都要查看c使用了哪些类?例如如果c.foo实例化B,则B被“使用”。如果c.foo调用静态方法G.bar(),则使用G.
注意:只是试图获得静态知道的类 - 我很好地错过了反射加载的类。
在python中,在modulefinder中找到了相同的功能: http://docs.python.org/library/modulefinder.html
答案 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;