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

import java.awt.*;

而不是导入一堆单独的类

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

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


当前回答

我更喜欢特定的导入,因为它允许我查看文件中使用的所有外部引用,而无需查看整个文件。(是的,我知道不一定会有完全合格的推荐信。但我尽量避免使用。)

其他回答

这里是对明星进口的投票。import语句用于导入包,而不是类。导入整个包要干净得多;这里指出的问题(例如java.sql.Date vs . java.util.Date)很容易通过其他方法来补救,而不是通过特定的导入来真正解决,当然也不能证明对所有类进行疯狂的迂腐的导入是正确的。没有什么比打开一个源文件并不得不翻看100条import语句更令人不安的了。

执行特定的导入会使重构更加困难;如果删除/重命名一个类,则需要删除其所有特定的导入。如果您将一个实现切换到同一个包中的不同类,则必须修复导入。虽然这些额外的步骤是可以自动化的,但它们实际上是对生产力的打击,没有真正的收益。

如果Eclipse在默认情况下不进行特定的类导入,那么每个人仍然会进行星型导入。我很抱歉,但是做特定的导入确实没有合理的理由。

下面是处理阶级冲突的方法:

import java.sql.*;
import java.util.*;
import java.sql.Date;

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

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

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

请参阅我的文章“按需进口是邪恶的”

简而言之,最大的问题是当一个类被添加到您导入的包中时,您的代码可能会中断。例如:

import java.awt.*;
import java.util.*;

// ...

List list;

在Java 1.1中,这很好;在java中找到列表。啊,没有冲突。

现在假设您检入了运行良好的代码,一年后,其他人使用Java 1.2编辑了它。

Java 1.2在Java .util中添加了一个名为List的接口。繁荣!冲突。完美工作的代码不再工作。

这是一个邪恶的语言特性。没有理由仅仅因为一个类型被添加到包中就停止编译……

此外,它使读者难以确定您使用的是哪个“Foo”。

最重要的是导入java.awt。*可以使您的程序与未来的Java版本不兼容:

假设你有一个名为“ABC”的类,你使用的是JDK 8,你导入java.util.*。现在,假设Java 9出来了,它在包Java中有一个新类。直到它碰巧也被称为“ABC”。您的程序现在不能在Java 9上编译,因为编译器不知道您的“ABC”名称是指您自己的类还是Java .awt中的新类。

如果只从java显式地导入这些类,就不会遇到这个问题。你实际使用的。

资源:

Java进口

忘掉混乱的命名空间……想想那些不得不在GitHub、vi、notepad++或其他非ide文本编辑器中阅读和理解你的代码的可怜人吧。

这个人必须煞费苦心地查找每个通配符作用域中所有类和引用中来自一个通配符的每个标记……只是想搞清楚到底发生了什么。

如果你只是为编译器编写代码——而且你知道你在做什么——我相信通配符没有问题。

但是,如果其他人(包括未来的您)希望一次阅读就能快速理解某个特定的代码文件,那么显式引用会有很大帮助。