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

kna*_*ten 300 java refactoring dead-code

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

还赞赏对一般战略/技术(特定工具除外)的建议.

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

Mik*_*x6r 220

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

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

  • 您想添加一个到市场的链接https://marketplace.eclipse.org/content/unnecessary-code-detector吗?这使得安装更容易,并回答了是否在较新版本的Eclipse上支持它的问题. (4认同)

Ber*_*own 64

CodePro最近由Google发布,带有Eclipse项目.它是免费且高效的.该插件具有" 查找死代码 "功能,具有一个/多个入口点.效果很好.

  • 所有链接都已过时。 (3认同)
  • 不幸的是,Google似乎将代码转储到了Eclipse项目上并忘记了所有相关内容. (3认同)

aku*_*uhn 39

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

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

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

  • @Outlaw AOP似乎是完美的用例. (14认同)
  • 如果您了解应用程序的类加载结构,则可以在类加载器上使用AOP来跟踪类加载事件.与生产系统之前的建议相比,这对生产系统的侵入性较小. (6认同)
  • 我喜欢这个答案,但有没有人知道如何在Java中执行此操作而不在每个类中明确添加日志记录?也许一些'代理'魔术? (5认同)
  • 这个答案对于动态语言来说非常好,但对于静态语言来说可能会更好.使用静态类型语言(除了反射),你可以确切地知道使用哪些方法,哪些不是,这是静态类型语言的最大优点之一,你应该使用它而不是这里描述的可变方法. (4认同)
  • @BillK比你想象的更多反思.例如,Spring在封面上做了很多魔术,包括反射.您的分析工具必须模拟它. (4认同)
  • 我已成功使用java.lang.instrument.Instrumentation.getAllLoadedClasses()和addTransformer()方法来记录加载的类.ClassFileTransformer不修改字节码; 它只是记录类名.您必须运行java代理才能访问Instrumentation实例. (2认同)
  • 实际上,正是出于这个原因,大多数基于反射的专业工具正在转向注释,而不仅仅是基于字符串的反射。反射几乎消除了静态类型语言的全部优势。 (2认同)

Dav*_*tas 30

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

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

ProGuard的一些用途是:

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

这里是列表死代码的示例:https://www.guardsquare.com/en/products/proguard/manual/examples#deadcode

  • 提供样本用法可以提供更好的答案. (8认同)

ski*_*ppy 26

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

但它非常手动.

  • 这很聪明......直到你从另一个类的未使用的代码中调用它. (8认同)
  • 也许不是理想的答案,但那真的很聪明. (4认同)

jam*_*esh 15

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

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

  • +1,因为它是一个很好的起点,但请记住,例如未使用的(尚未声明的)变量也会显示为绿色。 (2认同)

Ala*_*lan 13

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

  • FindBugs无法检测死的和未使用的代码,只能检测未使用的字段.见[answer](http://stackoverflow.com/questions/4721142/can-findbugs-detect-unused-public-methods/4752016#4752016). (4认同)

cle*_*tus 12

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

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

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

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

  • 开场判决太强烈了.与暂停问题一样(也经常被错误引用/滥用),没有完整的通用解决方案,但有很多特殊情况可供检测. (10认同)
  • 虽然对于具有eval和/或反射的语言没有通用的解决方案,但很多情况下代码都是无法访问的. (9认同)

小智 7

在Eclipse Goto Windows> Preferences> Java> Compiler> Errors/Warnings中
,将所有这些更改为错误.修复所有错误.这是最简单的方法.美妙的是,这将允许您在编写时清理代码.

截图Eclipse代码:

在此输入图像描述


Pet*_*rey 5

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

我还试图找到重复的代码作为减少代码量的方法.

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


Chr*_*101 5

Structure101 切片透视图将给出与"主"集群没有依赖关系的类或包的任何"孤儿"或"孤立 "的列表(和依赖关系图).