我正在开发一个库,我们想要确定我们使用了多少库。 I.E.我们想知道我们的库中有多少方法是公开的,但从未被调用过。
目标: 静态分析 确定在当前项目中调用包A中的每个公共方法的代码行数。如果调用次数为零,则应按此方式报告该方法。
答案 0 :(得分:9)
我相信你正在寻找这个eclipse插件 - > UCDetector
从文档(付费通知到第二个要点)
在较大规模上,如果要进行对象级静态分析,请查看IBM的这个工具 - > Structural Analysis for Java。它对于库,API等的对象分析非常有用。
答案 1 :(得分:3)
不完全是您要找的,但是:
使用代码覆盖工具(如Cobertura)可以完成类似的工作。他们不对源代码进行静态检查,而是检测字节码以在运行时收集度量。当然,您需要以运行所有使用模式的方式驱动应用程序,并且可能会错过罕见的代码路径。
在静态分析方面,也许这些工具可以帮助你(Apache项目使用它们来检查新版本的API兼容性,看起来这个任务与你想要做的事情有些相关):
答案 2 :(得分:3)
客户使用反射调用是静态分析中需要考虑的一个漏洞。因为没有办法确定某个特定方法是不是通过一些奇怪的反射方案来调用的。因此,运行和静态分析的组合可能是最好的。
答案 3 :(得分:1)
我认为你无法衡量一个类或一个功能需要“经常”的程度 有一些简单的问题:
结论:
我不知道你想要完成什么
如果要显示代码依赖关系,可以使用其他tools来执行此操作。如果您正在尝试测量代码执行,那么Java有profiler or benchmarks。如果您是统计极客,您会对RapidMiner;)
祝你好运!
答案 4 :(得分:1)
我建议JDepend向您展示包和类之间的依赖关系,非常适合查找循环依赖关系! http://clarkware.com/software/JDepend.html (它有一个eclipse插件:http://andrei.gmxhome.de/jdepend4eclipse/
以及其他指标的PMD http://pmd.sourceforge.net/
答案 5 :(得分:1)
IntelliJ有一个工具来检测可以有更多限制修饰符的方法,字段,类。它还可以快速修复应用这些更改,这也可以为您节省大量工作。如果您不想为此付费,您可以获得30天的eval许可证,这足以让您更改代码,这不是您经常需要做的事情。
BTW:IntelliJ有大约650次代码检查以提高代码质量,大约一半有自动修复,所以我建议花几天时间使用它来重构/整理你的代码。答案 6 :(得分:1)
请查看Dead Code Detector。它声称可以满足您的需求:使用静态分析查找未使用的代码。
答案 7 :(得分:0)
以下是一些Java代码覆盖工具列表。我个人没有使用过这些,但它可能会让你开始:
答案 8 :(得分:0)
Proguard也可以是一个选项(http://proguard.sourceforge.net/):
“ProGuard的一些用途是:
另见http://proguard.sourceforge.net/manual/examples.html#deadcode
答案 9 :(得分:0)
您可以使用ASM字节码分析库(http://asm.ow2.org)为此编写自己的实用程序(在阅读本文后的一个小时内)。您需要实现ClassVisitor和MethodVisitor。您将使用ClassReader来解析库中的类文件。
维护地图进行计数。键代表方法(见下文)。这是一些代码:
class MyClassVisitor {
// ...
public void visit(int version, int access, String name, ...) {
this.className = name;
}
public MethodVisitor visitMethod(int access, String name, String desc, ...):
String key = className + "." + name + "#" + desc;
if (!map.containsKey() {
map.put(key, 0);
}
return new MyMethodVisitor(map);
}
// ...
}
void class MyMethodVisitor {
// ...
public visitMethodInsn(int opcode, String name, String owner, String desc, ...) {
String key = owner + "." + name + "#" + desc;
if (!map.containsKey() {
map.put(key, 0);
}
map.put(key, map.get(key) + 1);
}
// ...
}
基本上就是这样。你正在以这样的方式开始表演:
Map<String,Integer> map = new HashMap<String,Integer>();
for (File classFile : my library) {
InputStream input = new FileInputStream(classFile);
new ClassReader(input).accept(new MyClassVisitor(map), 0);
input.close();
}
for (Map.Entry<String,Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
System.out.println("Unused method: " + entry.getKey());
}
}
享受!