考虑以下导入语句:
导入java.io.*;//有道理
导入javax.servlet.*;
导入javax.servlet.http.*;
我们不是已经包含了“import javax.servlet.;”吗?因此它也会自动包含另一个导入语句,即“import javax.servlet.http.;”?
为什么为 http 显式定义“import javax.servlet.http.*”?
请澄清并让我知道我是否错了。
最佳答案
是的,您确实需要为每个包进行通配符导入。
为什么?就 JLS 而言,“com.example”和“com.example.pkg”是不相关的软件包。 JLS 中提到了子包的概念,但没有相关的语义。特别是不在“访问”规则中。 JLS 7.1说:"The hierarchical naming structure for packages is intended to be convenient for organizing related packages in a conventional manner, but has no significance in itself other than the prohibition against a package having a subpackage with the same simple name as a top level type (§7.6) declared in that package.
For example, there is no special access relationship between a package named
oliver
and another package namedoliver.twist
, or between packages namedevelyn.wood
andevelyn.waugh
. That is, the code in a package namedoliver.twist
has no better access to the types declared within packageoliver
than code in any other package."
(允许导入许多不相关包的构造会产生不良后果......见下文。)
但是为什么呢?因为这就是语言的设计方式。
但是为什么呢?您需要询问 Java 语言设计团队在 20 世纪 90 年代初做出设计决策时的想法。
<小时/>但也许我们可以看到如果存在多包通配符导入会发生什么。
考虑这个包结构,这是一种非常常见的模式:
com.example.weazellib - contains the public API classes for the library
com.example.weazellib.impl - contains implementation classes that
shouldn't be used by external clients
众所周知,程序员都是懒惰的(好吧,很多人都是如此),所以有些程序员可能会这样写:
import com.example.weazellib.** // hypothetical syntax
他/她现在将在该类命名空间中拥有外部 API 类和内部类,并且很容易意外创建对内部的依赖关系。
(在你说“将内部类包设为私有(private)”之前...这是行不通的。 com.example.weazellib
中的类需要能够使用 com.example.weazellib.impl
中的类.如果后者是包私有(private)的,那么前者将无法使用它们。)
相比之下,在 Java 没有导入包“树”的通配符的情况下,您不能意外地这样做。您必须刻意导入 impl
包裹。这是一件好事,比为多个包编写通配符导入的“不便”重要得多。
另一个问题是通配符导入不利于源代码的长期稳定性,而 super 通配符会使情况变得更糟。
假设程序员决定导入 com.example.weazellib
和com.example.weazellib.impl
在他的代码中做正确的事情......并使用 super 通配符来导入两者。假设他编写代码以使用 com.example.weazellib.impl.ToesImpl
...如ToesImpl
.
现在考虑如果“weazellib”开发人员添加第三个包 com.example.weazellib.impl2
会发生什么包含替代实现类...与 impl
中的类具有相同的简单名称;例如我们现在有这样的类(class):
com.example.weazellib.impl.ToesImpl
com.example.weazellib.impl2.ToesImpl
会发生什么?现在程序员的代码中有一个编译错误。 ToesImpl
是不明确的...因为 super 通配符导入的影响从以前不存在的包中提取类名。
请注意,常规通配符导入也存在同样的问题。这就是为什么很多人不使用通配符导入的原因。但毫无疑问, super 通配符会让问题变得更糟。
关于java - 为什么要定义多个导入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15857310/