java - 为什么要定义多个导入?

标签 java import wildcard

考虑以下导入语句:

导入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 named oliver.twist, or between packages named evelyn.wood and evelyn.waugh. That is, the code in a package named oliver.twist has no better access to the types declared within package oliver 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.weazellibcom.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/

相关文章:

java - 谷歌云语音转文本给出 0 结果

java - 如何将现有的Java程序转移到Android? (要导入什么)

linux - 如何将通配符参数传递给 bash 文件

css - CSS 值中的通配符

node.js - 查看树中是否有与 blob 匹配的文件的最快方法

java - 小部件的 runOnUiThread 方法模拟?

java - 字符串缓冲区行为

java - 修改 JTable 中不同行的单元格编辑器

python - 通过文件路径导入模块时使用 Python 多处理

python - 如何在 Python 中将参数传递给导入的脚本