如何在java项目中查找未使用/死代码

时间:2008-10-02 14:22:53

标签: java refactoring dead-code

您使用哪些工具在大型Java项目中查找未使用/死代码?我们的产品已经开发了几年,手动检测不再使用的代码变得非常困难。但是,我们尝试尽可能多地删除未使用的代码。

对一般策略/技术(特定工具除外)的建议也表示赞赏。

编辑请注意,我们已经使用了代码覆盖率工具(Clover,IntelliJ),但这些工具没有多大帮助。死代码仍然有单元测试,并显示为覆盖。我想一个理想的工具可以识别出具有很少其他代码的代码集,具体取决于它,允许docues手动检查。

21 个答案:

答案 0 :(得分:219)

运行良好的Eclipse插件是Unused Code Detector

它处理整个项目或特定文件,并显示各种未使用/死代码方法,以及建议可见性更改(即可以保护或私有的公共方法)。

答案 1 :(得分:64)

谷歌最近发布了

CodePro项目。它是免费且高效的。该插件具有带有一个/多个入口点的“Find Dead Code”功能。效果很好。

答案 2 :(得分:38)

我会检测正在运行的系统以保存代码使用日志,然后开始检查未使用数月或数年的代码。

例如,如果您对未使用的类感兴趣,则可以检测所有类以在创建实例时进行记录。然后,一个小脚本可以将这些日志与完整的类列表进行比较,以找到未使用的类。

当然,如果你采用方法级别,你应该记住性能。例如,这些方法只能记录它们的首次使用。我不知道如何用Java做得最好。我们在Smalltalk中完成了这项工作,Smalltalk是一种动态语言,因此允许在运行时进行代码修改。我们使用日志记录调用对所有方法进行检测,并在首次记录方法后卸载日志记录代码,因此在一段时间后不再出现性能损失。也许在Java中可以使用静态布尔标志来完成类似的事情......

答案 3 :(得分:27)

我很惊讶ProGuard这里没有提到。它是最成熟的产品之一。

  

ProGuard是一个免费的Java类文件收缩器,优化器,混淆器,   和预验证。它检测并删除未使用的类,字段,   方法和属性。它优化字节码并删除未使用的   说明。它重命名剩余的类,字段和方法   使用简短无意义的名字。最后,它预先验证了已处理的   Java 6或Java Micro Edition的代码。

     

ProGuard的一些用途是:

     
      
  • 创建更紧凑的代码,更小的代码存档,更快的网络传输,更快的加载和更小的内存   脚印。
  •   
  • 使程序和库更难以进行逆向工程。
  •   
  • 列出死代码,因此可以从源代码中删除。
  •   
  • 重新定位和预验证Java 6或更高版本的现有类文件,以充分利用其更快的类加载。
  •   

此处列出死代码示例:https://www.guardsquare.com/en/products/proguard/manual/examples#deadcode

答案 4 :(得分:26)

我在Eclipse中已经知道的一件事,就是在一个单独的类中,将所有方法改为私有,然后看看我得到了什么样的抱怨。对于使用的方法,这将引发错误,并且我将它们返回到我能够的最低访问级别。对于未使用的方法,这将引发有关未使用方法的警告,然后可以删除这些方法。作为奖励,您经常会找到一些可以而且应该被私有的公共方法。

但这是非常手动的。

答案 5 :(得分:15)

使用测试覆盖率工具来检测代码库,然后运行应用程序本身,而不是测试。

EmmaEclemma会为您提供很好的报告,说明为任何给定的代码运行运行的类的百分比。

答案 6 :(得分:13)

我们已经开始使用Find Bugs来帮助识别代码库的目标丰富的重构环境中的一些功能。我还会考虑Structure 101来识别代码库架构中太复杂的位置,以便了解真实沼泽的位置。

答案 7 :(得分:12)

理论上,您无法确定性地找到未使用的代码。这是一个数学证明(嗯,这是一个更一般的定理的特例)。如果你很好奇,请查看暂停问题。

这可以通过多种方式在Java代码中体现出来:

  • 根据用户输入,配置文件,数据库条目等加载类;
  • 加载外部代码;
  • 将对象树传递给第三方库;

话虽这么说,我使用IDEA IntelliJ作为我选择的IDE,并且它具有广泛的分析工具,用于查找模块之间的依赖关系,未使用的方法,未使用的成员,未使用的类等。它非常聪明,就像私有方法一样。被调用的标记未被标记,但公共方法需要更广泛的分析。

答案 8 :(得分:7)

在Eclipse Goto Windows>中偏好> Java>编译器>错误/警告
并将所有这些更改为错误。修复所有错误。这是最简单的方法。美妙的是,这将允许您在编写时清理代码。

截图Eclipse代码:

enter image description here

答案 9 :(得分:5)

IntelliJ具有代码分析工具,用于检测未使用的代码。您应该尝试尽可能多地创建非公共字段/方法/类,这将显示更多未使用的方法/字段/类

我还会尝试找到重复的代码,以减少代码量。

我的最后一个建议是尝试查找开源代码,如果使用它将使您的代码更简单。

答案 10 :(得分:5)

Structure101 slice perspective将给出与“主”集群没有依赖关系的类或包的任何“孤儿”或“孤立groups”的列表(和依赖关系图)。

答案 11 :(得分:3)

DCD不是某个IDE的插件,但可以从ant或独立运行。它看起来像一个静态工具it can do what PMD and FindBugs can't。我会尝试的。

P.S。如下面的评论中所述,该项目现在位于GitHub

答案 12 :(得分:2)

有一些工具可以分析代码并提供代码覆盖率数据。这使您可以看到(代码运行时)调用了多少。您可以使用任何这些工具来了解您拥有多少孤儿代码。

答案 13 :(得分:2)

  • FindBugs非常适合这类事情。
  • PMD(Project Mess Detector)是另一种可以使用的工具。

但是,两者都找不到工作空间中未使用的公共静态方法。如果有人知道这样的工具,请告诉我。

答案 14 :(得分:1)

代码覆盖工具,例如Emma,Cobertura和Clover,将检测您的代码并通过运行一系列测试来记录它的哪些部分被调用。这非常有用,应该是您开发过程中不可或缺的一部分。它将帮助您确定测试套件对代码的覆盖程度。

然而,这与识别真实死代码不同。它仅识别测试覆盖(或未覆盖)的代码。这可能会给你误报(如果你的测试不包括所有场景)以及漏报(如果你的测试访问的代码实际上从未在现实场景中使用过)。

我认为真正识别死代码的最佳方法是在实时运行环境中使用覆盖工具检测代码,并在较长时间内分析代码覆盖率。

如果你在负载均衡的冗余环境中运行(如果不是,为什么不呢?)那么我认为仅对仪器的一个实例进行检测并配置负载均衡器是有意义的,这样随机但很小,部分用户在已检测的实例上运行。如果你在很长一段时间内这样做(为了确保你已经涵盖了所有真实世界的使用场景 - 这种季节性变化),你应该能够确切地看到你的代码的哪些区域在真实世界的使用下被访问以及哪些部分被访问真的从来没有被访问,因此死代码。

我从来没有亲眼见过这一点,也不知道上述工具如何用于检测和分析未通过测试套件调用的代码 - 但我相信它们可以。

答案 15 :(得分:1)

用户覆盖工具,例如EMMA。但它不是静态工具(即它需要通过回归测试实际运行应用程序,并通过所有可能的错误情况,这是,嗯,不可能:))

尽管如此,EMMA非常有用。

答案 16 :(得分:1)

有一个Java项目 - Dead Code Detector(DCD)。对于源代码,它似乎不能很好地工作,但对于.jar文件 - 它真的很好。另外,您可以按类和方法进行过滤。

答案 17 :(得分:1)

Netbeans 这是Netbeans dead code detector的插件。

如果它可以链接并突出显示未使用的代码会更好。您可以在此投票和评论:Bug 181458 - Find unused public classes, methods, fields

答案 18 :(得分:0)

我找到了Clover覆盖工具,它可以编写代码并突出显示所使用和未使用的代码。与Google CodePro Analytics不同,它也适用于WebApplications(根据我的经验,我可能对Google CodePro不正确)。

我注意到的唯一缺点是它不考虑Java接口。

答案 19 :(得分:0)

Eclipse可以显示/突出显示无法访问的代码。 JUnit可以向您显示代码覆盖率,但您需要进行一些测试,并且必须确定相关测试是否缺失或代码是否真的未使用。

答案 20 :(得分:0)

我使用Doxygen开发一个方法调用映射来定位从未调用过的方法。在图表上,您将找到没有调用者的方法集群的孤岛。这对图书馆不起作用,因为您需要始终从某个主入口点开始。