为什么我们每次都使用前缀 "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 接口及其子接口的源代码时,我注意到大多数接口实现了 Cloneable
和 java.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 {
...
}
...等等
我也注意到了:
Collection
接口,TreeSet
LinkedHashSet
等属于package java.util;
Cloneable
接口属于package java.lang;
Serializable
属于 package java.io;
现在我的问题是为什么我们要在 Serializable
之前添加前缀 java.io
(如上所示)而不是像 Collection 界面中那样导入 import java.io.Serializable;
。
有一个接口sunw.io.Serializable
,所以他们很可能想区分这两者。然而,不可能说出这到底是什么原因。也许这是政策,也许他们 运行 由于导入了错误的错误而难以调试错误...
这就是 Java 导入的工作方式:
java.lang
中的所有 classes 和界面自动可见。
- 同一包中的任何 class 或接口自动对该包中的其他 class 和接口可见。
- 另一个包中的任何class或接口必须显式声明(包和class名称)或导入。
鉴于这些规则:
AbstractSet
、NavigableSet
与 TreeSet
在同一个包中,因此自动可见。
Cloneable
在 java.lang
中自动可见。
Serializable
在 java.io
中,因此明确声明(但也适用于导入)。
在询问为什么要使用显式声明或导入时,在大多数情况下,这取决于样式。在大多数情况下,使用 import 是因为它使代码更简洁。
唯一的例外是使用两个或多个 class 具有相同名称的 es 或接口。在这种情况下,您应该明确声明每个用途。
这背后没有很好的理由。 类 没有其他导入语句,并且 Serializable
在这些文件中仅在一个地方被引用,因此很容易看出为什么作者可能不想导入。
作为另一个兴趣点,TreeMap
在 OpenJDK 8 中既包含导入语句又使用完全限定名称。
您提到的 classes(TreeSet
、LinkedHashSet
等)根本没有任何导入,如果它总是使用完整的 class 名称属于java.lang
或java.util
以外的包
我会说这是一种不好的做法,但我们不能责怪 Josh Bloch 先生 :)
我的问题不是关于对 Serializable 接口用法的技术理解。 这些答案已经解释过了 [1] & [2] among others
我的问题是从句法的角度。
在查看 Collection 接口及其子接口的源代码时,我注意到大多数接口实现了 Cloneable
和 java.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 {
...
}
...等等
我也注意到了:
Collection
接口,TreeSet
LinkedHashSet
等属于package java.util;
Cloneable
接口属于package java.lang;
Serializable
属于package java.io;
现在我的问题是为什么我们要在 Serializable
之前添加前缀 java.io
(如上所示)而不是像 Collection 界面中那样导入 import java.io.Serializable;
。
有一个接口sunw.io.Serializable
,所以他们很可能想区分这两者。然而,不可能说出这到底是什么原因。也许这是政策,也许他们 运行 由于导入了错误的错误而难以调试错误...
这就是 Java 导入的工作方式:
java.lang
中的所有 classes 和界面自动可见。- 同一包中的任何 class 或接口自动对该包中的其他 class 和接口可见。
- 另一个包中的任何class或接口必须显式声明(包和class名称)或导入。
鉴于这些规则:
AbstractSet
、NavigableSet
与TreeSet
在同一个包中,因此自动可见。Cloneable
在java.lang
中自动可见。Serializable
在java.io
中,因此明确声明(但也适用于导入)。
在询问为什么要使用显式声明或导入时,在大多数情况下,这取决于样式。在大多数情况下,使用 import 是因为它使代码更简洁。
唯一的例外是使用两个或多个 class 具有相同名称的 es 或接口。在这种情况下,您应该明确声明每个用途。
这背后没有很好的理由。 类 没有其他导入语句,并且 Serializable
在这些文件中仅在一个地方被引用,因此很容易看出为什么作者可能不想导入。
作为另一个兴趣点,TreeMap
在 OpenJDK 8 中既包含导入语句又使用完全限定名称。
您提到的 classes(TreeSet
、LinkedHashSet
等)根本没有任何导入,如果它总是使用完整的 class 名称属于java.lang
或java.util
我会说这是一种不好的做法,但我们不能责怪 Josh Bloch 先生 :)