为什么我们每次都使用前缀 "java.io." 而不是导入 java.io.Serializable 接口

why we use prefix "java.io." everytime and not import java.io.Serializable interface

我的问题不是关于对 Serializable 接口用法的技术理解。 这些答案已经解释过了 [1] & [2] among others

我的问题是从句法的角度。

在查看 Collection 接口及其子接口的源代码时,我注意到大多数接口实现了 Cloneablejava.io.Serializable,如下所示:

public class TreeSet<E> extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, java.io.Serializable{
...
}


public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
...
}

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
...
}

...等等

我也注意到了:

现在我的问题是为什么我们要在 Serializable 之前添加前缀 java.io(如上所示)而不是像 Collection 界面中那样导入 import java.io.Serializable;

有一个接口sunw.io.Serializable,所以他们很可能想区分这两者。然而,不可能说出这到底是什么原因。也许这是政策,也许他们 运行 由于导入了错误的错误而难以调试错误...

这就是 Java 导入的工作方式:

  • java.lang 中的所有 classes 和界面自动可见。
  • 同一包中的任何 class 或接口自动对该包中的其他 class 和接口可见。
  • 另一个包中的任何class或接口必须显式声明(包和class名称)或导入。

鉴于这些规则:

  • AbstractSetNavigableSetTreeSet 在同一个包中,因此自动可见。
  • Cloneablejava.lang 中自动可见。
  • Serializablejava.io 中,因此明确声明(但也适用于导入)。

在询问为什么要使用显式声明或导入时,在大多数情况下,这取决于样式。在大多数情况下,使用 import 是因为它使代码更简洁。

唯一的例外是使用两个或多个 class 具有相同名称的 es 或接口。在这种情况下,您应该明确声明每个用途。

这背后没有很好的理由。 类 没有其他导入语句,并且 Serializable 在这些文件中仅在一个地方被引用,因此很容易看出为什么作者可能不想导入。

作为另一个兴趣点,TreeMap 在 OpenJDK 8 中既包含导入语句又使用完全限定名称。

您提到的 classes(TreeSetLinkedHashSet 等)根本没有任何导入,如果它总是使用完整的 class 名称属于java.langjava.util

以外的包

我会说这是一种不好的做法,但我们不能责怪 Josh Bloch 先生 :)