使用单个语句更方便,更简洁,比如

import java.awt.*;

而不是导入一堆单独的类

import java.awt.Panel;
import java.awt.Graphics;
import java.awt.Canvas;
...

在import语句中使用通配符有什么问题?


当前回答

There is no runtime impact, as compiler automatically replaces the * with concrete class names. If you decompile the .class file, you would never see import ...*. C# always uses * (implicitly) as you can only using package name. You can never specify the class name at all. Java introduces the feature after c#. (Java is so tricky in many aspects but it's beyond this topic). In Intellij Idea when you do "organize imports", it automatically replaces multiple imports of the same package with *. This is a mandantory feature as you can not turn it off (though you can increase the threshold). The case listed by the accepted reply is not valid. Without * you still got the same issue. You need specify the pakcage name in your code no matter you use * or not.

其他回答

郑重声明: 当您添加导入时,您也在指示您的依赖项。

您可以很快看到文件的依赖关系(不包括相同名称空间的类)。

性能:由于字节码相同,对性能没有影响。 尽管这会导致一些编译开销。

编译:在我的个人机器上,编译一个空白类而不导入任何东西需要100毫秒,但导入java时是同一个类。*占用170毫秒。

为什么在Java导入语句中使用通配符是不好的?

如果你正在使用一个IDE(这是你应该做的),并且有比你更多的代码所有者,使用通配符导入是不好的,因为它:

对团队其他成员隐瞒信息 提供给您的只是虚假的好处(使用IDE功能比使用通配符导入更好地解决的事情)

大多数“使用通配符”的支持者都专注于个人:我不想维护列表,我不想看到混乱等等。下面是几个常见的例子:

维护更加困难——当您想要在源代码中引入一个新类时,您必须手动添加import语句 重构更加困难——如果代码被移动了,那么导入语句就必须更新 减少混乱,整理文件内容——这里的目标是“消除干扰”。

These arguments were more convincing before IDEs did all of that automatically. If you're using a plain text editor instead of an IDE, then these arguments have some merit. But if you're using a plain text editor, you are already subjecting yourself to a number of other much more significant inefficiencies, and managing import statements is just one among many things that you should stop doing by hand. IDEs offer automatic management of imports, powerful refactoring tools, and folding (hiding) of any parts of the code you don't want to see.

对于“避免通配符”的支持者,有很多例子,但我只指出一个:

清晰度——特别是当有新人进入代码库时。他们将带着问题来到这里,并在探索代码的过程中继续发现新的问题。对于这个新的代码贡献者,通配符导入语句不能回答任何问题,在最坏的情况下可能会产生混乱、误解和新问题。相反,对于显式导入(并使用IDE),最坏的情况是中性的:没有提供新的信息;最好的情况是,它不仅可以减少歧义,而且还可以提供答案。

在一天结束的时候,它帮助整个团队降低(尽管是以一种很小的方式)代码的复杂性,减少混乱,增加清晰度。

唯一的问题是它会混淆本地名称空间。例如,假设您正在编写一个Swing应用程序,因此需要java.awt。事件,并且还与公司的日历系统进行接口,该系统具有com.mycompany.calendar.Event。如果你使用通配符方法导入两者,会发生以下三种情况之一:

event和com.mycompany.calendar之间存在完全的命名冲突。事件,因此您甚至无法编译。 您实际上只导入了一个(两个导入中只有一个导入了。*),但它是错误的,并且您很难弄清楚为什么代码声称类型是错误的。 在编译代码时,没有com.mycompany.calendar。事件,但当他们后来添加一个时,您以前有效的代码突然停止编译。

显式列出所有导入的好处是,我可以一眼看出您打算使用哪个类,这使得代码的阅读更加容易。如果您只是在做一个快速的一次性的事情,那么没有什么明显的错误,但是未来的维护者会因为您的清晰而感谢您。

It helps to identify classname conflicts: two classes in different packages that have the same name. This can be masked with the * import. It makes dependencies explicit, so that anyone who has to read your code later knows what you meant to import and what you didn't mean to import. It can make some compilation faster because the compiler doesn't have to search the whole package to identify depdencies, though this is usually not a huge deal with modern compilers. The inconvenient aspects of explicit imports are minimized with modern IDEs. Most IDEs allow you to collapse the import section so it's not in the way, automatically populate imports when needed, and automatically identify unused imports to help clean them up.

我工作过的大多数使用大量Java的地方都将显式导入作为编码标准的一部分。我有时仍然使用*来快速创建原型,然后在产品化代码时展开导入列表(一些ide也会为您这样做)。