2009-04-20 81 views
5

我的工作,我们要确定有多少我们的图书馆正在使用的库。 I.E.我们想知道我们图书馆有多少种方法是公开的,但从未被调用过。的Java代码使用检查

目标: 静态分析 确定有多少行代码调用当前项目中程序包A中的每个公用方法。如果调用次数为零,则方法应该如此报告。

+0

听起来就像你想要类似Cobertura或Emma那样监视正在运行的应用程序,而不是依赖一组单元测试覆盖率? – 2009-06-01 18:02:50

回答

9

我相信你正在寻找这个Eclipse插件 - >UCDetector

从文档(收费通知到第二个要点)

  • 不需要的(死的)代码
  • 代码中的知名度可以更改为保护,默认或 私人领域的
  • 方法,这可能是最后的

更大规模上,如果你想要做的对象级静态分析,看看在IBM的这个工具 - >Structural Analysis for Java。这对于库,API等对象分析非常有用。

3

不正是你所寻找的,但是:类似

东西用代码覆盖工具完成(如Cobertura)。他们不会对源代码进行静态检查,而是在运行时检测字节码以收集指标。当然,您需要以一种可以执行所有使用模式的方式来驱动应用程序,并且可能会错过罕见的代码路径。

在静态分析前,也许这些工具可以帮助你(Apache项目使用它们来检查新版本的API的兼容性,好像这个任务具有一定的相关你正在尝试做的):

  • Clirr是一种工具,检查Java库与旧版本的二进制和源代码兼容。基本上,你给它两套jar文件,Clirr公开api中的变更列表。
  • JDiff是的Javadoc的doclet生成所有的包,类,构造函数,方法和字段已被删除的HTML报告,补充或以任何方式改变,包括他们的文档,当两个API进行了比较。
1

我不认为你能够衡量一个类或函数是如何“经常”需要的。
有一些简单的问题:

  • 什么定义,如果你的游戏库的使用统计是“正常”或“异常”?在游戏中过于频繁地杀死自己是不对的?你会更频繁地使用“killScreen”类,就像一个好的玩家。
  • 什么定义“多”?时间或使用次数? POJO会消耗很少的时间,但使用相当频繁。

结论:
我不知道你在做什么。
如果你想显示你的代码依赖关系,还有其他tools这样做。如果您正在尝试测量代码执行情况,那么Java有profiler or benchmarks。如果你是一个怪胎统计,你会发现RapidMiner;)

与祝你好运!

3

客户端使用反射调用是静态分析中需要考虑的一个漏洞。因为无法确切知道某个特定的方法没有通过一些奇怪的反射方案被调用。所以,运行时和静态分析的组合可能是最好的。

0

你可以写你自己的效用,请参阅使用ASM字节码分析库(http://asm.ow2.org)(一小时内看完这个)。你需要实现一个ClassVisitor和一个MethodVisitor。您将使用ClassReader来解析库中的类文件。

  • 您的ClassVisitor的visitMethod(..)将针对每个声明的方法进行调用。
  • 您的方法访问方法Insn(..)将被称为每个被调用的方法。

保持地图进行计数。键代表方法(见下文)。这里有一些代码:

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); 
    } 
    // ... 
} 

基本就是这样。 Your're开始与这样的事情:

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()); 
    } 
} 

享受!

+0

如果方法A调用方法B,则即使方法A未使用,方法B也会被标记为“已使用”,所以这不是正确的方法。你需要对“used”进行传递封闭。 – 2009-07-10 09:38:58

1

IntelliJ有一个工具来检测方法,字段,类可以有更多的限制修饰符。它也有一个快速修复应用这些变化,可以为您节省很多工作。如果您不想为此付费,您可以获得30天的eval许可证,该许可证有足够的时间来更改您的代码,而不是您经常需要执行的操作。

顺便说一句:IntelliJ有大约650个代码检查来提高代码质量,大约一半有自动修复,所以我建议花几天用它来重构/整理你的代码。

1

请看看Dead Code Detector。它声称只做你正在寻找的东西:使用静态分析找到未使用的代码。