除了减少混乱之外,还有其他清理Java中未使用的导入的原因吗?


99

是否有充分的理由避免使用Java中未使用的import语句?据我了解,它们在编译器中,所以大量未使用的导入不会对编译后的代码产生任何影响。只是为了减少混乱并避免命名冲突吗?

(我问是因为Eclipse发出了有关未使用导入的警告,这在我开发代码时有点烦人,因为在确定完成类设计之前,我不想删除导入。)

Answers:


86

如果您不删除导入,我认为不会出现性能问题或类似问题。

但在极少数情况下,例如导入列表接口,可能会存在命名冲突。

在Eclipse中,您始终可以使用快捷方式(取决于OS-Win:Ctrl + SHIFT + O和Mac:)COMMAND + SHIFT + O来组织导入。然后,Eclipse清理导入部分,删除所有过时的导入等。如果再次需要导入的东西,eclipse将在用结束语句时自动添加它们Ctrl + SPACE。因此,无需在类中保留未使用的代码。

通常,未使用的代码会分散您和其他人的注意力,同时阅读代码并在您的活动代码中留下一些内容,因为也许以后我需要它,这通常被视为不良做法。


22
在Windows上实际上是Ctrl + Shift + O。
马特·鲍尔

1
在Linux上按Ctrl + Shift + O也可以。在BSD上可能相同。
WhyNotHugo 2012年

2
进行组织导入操作的另一种方法是单击ctrl+3(至少在windwos上),然后键入导入。显然,它比ctrl + shift + O慢,但是它是一种快速找到它的方式(以及您想起或试图找到的许多其他动作),即使您不记得它的具体快捷方式了。
epeleg 2013年

53

一种可能是,如果您从类路径中删除了导入引用的类,则不会出现无用的愚蠢的编译器错误。当您执行“在哪里使用”搜索时,您不会得到误报。

另一个(但这本质上是非常具体的)是未使用的导入与另一个导入的命名冲突,从而导致您不必要地使用完全限定名称。

附录:今天,构建服务器由于内存不足错误而开始编译失败(甚至没有运行测试)。它永远运行良好,并且签入对构建过程没有任何更改,也没有任何可以解释这一点的重大增加。在尝试将内存设置(这是在64位CentOS上运行64位JVM!)增加到超出客户端可以编译的范围之后,我一一检查了签入。

开发人员使用并放弃了不正确的导入(他们使用了该类,将其自动导入,然后意识到这是一个错误)。未使用的导入拉入了应用程序的整个单独层,尽管未将IDE配置为将它们分开,但是构建过程是这样。单个导入拖入了太多的类,编译器试图在类路径中没有相关的依赖库的情况下尝试进行编译,从而导致了太多的问题,从而导致了内存不足错误。解决了由未使用的导入引起的此问题花费了一个小时。


4
@Yishai,如果使用Eclipse,请查看Save Actions,它可以在每次保存时标准化源代码。
托尔比约恩Ravn的安徒生

2
@EJP,尽管它们不影响生成的字节码,但是编译器需要解析它们才能理解需要创建的字节码。
Yishai 2010年

3
@EJP,整个附录都在讨论编译时间(“构建服务器开始编译失败”)。
Yishai 2010年

1
我仍然不明白仅凭进口会如何导致所有这一切?
托尔比约恩Ravn的安徒生

1
@Yishai对不起,但我不相信。您误诊了这一点。除非实际使用了该类,否则导入应该没有这种效果。import语句所做的所有事情都是告诉编译器该类所在的包。编译器仅在需要有关该类的类型信息时才尝试隐式编译。
罗恩侯爵

9

从纯粹的角度来看,任何依赖关系都是对产品的“约束”,因此可能在以后引起维护问题。

例如,假设您的程序使用com.XYZObjectPool类,并且稍后您决定不使用它,但从不删除导入。如果现在有人想实例化org.WVYObjectPool并仅引用ObjectPool,则直到出现转换问题或调用问题,他们才会收到有关它的任何警告。

顺便说一下,这不是不现实的情况。每当您使用Eclipse询问您要导入哪个特定版本的X,并从许多软件包中选择一个时,都会出现这样的情况:如果您在其中进行了导入,则可能会在不知情的情况下选择错误。

无论哪种方式,您都可以要求Eclipse为您清理这些内容


3

警告?要求Eclipse自动为您清理它们。这就是IntelliJ所做的。如果它足够聪明可以警告您,则应该足够聪明来清理它们。我建议您寻找一个Eclipse设置,以告诉它停止进行此类操作。


4
那就是保存动作。就我个人而言,我喜欢Eclipse仅在您明确要求时才更改您的代码。
托尔比约恩Ravn的安徒生

1
@Thorbjørn:同意,特别是如果这是我已经停止使用了一点的课程,但是我希望不久以后会再次加入。
Donal Fellows 2010年

2
@Donal,这就是Ctrl-Space的用途。
托尔比约恩Ravn的安徒生

3

这与对维护有用的程序的清晰度有关。

如果您必须维护一个程序,则会发现每行导入一个类是多么有用。

考虑以下情形:

import company.billing.*;
import company.humanrerources.*;

// other imports 


class SomeClass {
      // hundreds or thousands of lines here... 
    public void veryImportantMethod() {
      Customer customer;
      Employee comployee;
      Department dept. 
      // do something with them
     }
 }

当您修正或维护一段代码(或仅阅读它)时,对读者来说,了解所使用的类属于哪个包非常有帮助。如上所示,使用通配符导入无济于事。

即使是使用IDE,也不想将鼠标悬停或跳转到声明和返回,如果从功能上理解当前代码所依赖的其他程序包和类,则更加容易。

如果这是用于个人项目还是较小的项目,那实际上没有关系,但是对于必须由其他开发人员使用(并且经过多年维护)的较大项目,这是必须的。

绝对没有任何性能差异。


3

仅供参考,这让我失望了,因为我不认为组织进口实际上会删除未使用的进口,我认为它只是对它们进行了排序。

例如,在开发或测试中遇到问题并注释掉一些代码时,在保存操作期间自动删除导入引起了我的不满。保存时,注释部分的代码所使用的导入将被删除。有时这不是问题,因为您可以撤消(Ctrl+ Z)更改,但是其他时候,它并不像您进行其他更改那样简单。我还有一个问题,当我取消注释代码时(我之前已注释掉然后保存,因此删除了该代码的导入),它会自动尝试猜测所需的导入并选择了错误的导入(例如,我认为我有一个StringUtils正在使用的类,并且从错误的库中选择了另一个具有相同名称的类)。

我宁愿手动组织导入,而不是将其作为保存操作。


2

对于eclipse,我使用以下命令:窗口->首选项-> java->编辑器->保存操作->选中复选框以进行组织导入(那里还有很多其他有用的东西,例如格式设置,字段最终确定等)。 )。因此,当我保存文件时,eclipse会为我删除unessacry导入。我认为,如果您不需要某些东西,请将其删除(或让其通过Eclipse删除)。


2

您可以注释掉未使用的import语句,并且警告不会打扰您,但是您可以看到所拥有的内容。


2
@DimaSan实际上是这样的:这个问题说,在确定完成类设计之前,我不想删除导入。
Vee

1

不会对性能造成任何影响,但是为了便于阅读,您可以使其变得干净。在Eclipse和IntelliJ IDEA中,删除未使用的导入都是非常简单的。

Windows / Linux-    Ctrl+ Shift+O

Mac-                        Cmd+ Shift+O

IntelliJ IDEAAndroid Studio

Windows / Linux-    Ctrl+ Alt+O

Mac-                        Cmd+ Alt+O


0

几年前,我在某处读到,每个导入的类都将在运行时随导入类一起加载。因此,删除未使用的软件包(尤其是整个软件包)将减少内存开销。尽管我认为Java的现代版本可以解决这个问题,但是可能不再是原因。

顺便说一句,使用eclipse,您可以使用Ctrl+ Shift+ O来组织导入,但是每次保存Java文件时,您也可以配置一个“清理器”来处理这些事情(以及许多其他事情)。


嗯..如果那是行为的话,我会感到惊讶。我知道直到第一次使用类,或者直到自定义加载器明确要求它们才初始化类(即调用静态初始化器)。但是,如果“加载”只是表示“读入内存但未处理”,则可能,尽管我对此表示怀疑。
基普

实际上,经过进一步思考,应该很容易进行测试。使用未使用的导入来编译代码,然后使用“反编译”工具,查看未使用的导入是否仍然存在。如果不是,那么它们要么被编译器删除,要么只是为了方便程序员。
基普

4
你在哪里读的?这是完全完全不正确的,而且一直存在。该代码引用的每个类都将被加载,包括导入。
罗恩侯爵

0

对我来说,在我在代码清理期间删除导入的类并在git中进行删除而不在本地测试构建后,控制器类中一个未使用的类导入在Jenkins构建中造成了编译问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.