我正在学习Java语言规范,我对JLS §7.4.3 - Observability of a Package中"Observability of a Package"
的含义有疑问:
当且仅当:
时,包是可观察的
- 包含声明包的编译单元是可观察的(第7.3节)。
- 可以观察到包装的子包装。
我的问题是
A subpackage of the package is observable
答案 0 :(得分:1)
JLS中有四个概念,它们很精确:
1)编译单元是可观察的 2)编译单元始终是可观察的 3)包装是可观察的 4)包装总是可观察的
1)让我们假设编译单元“A”是可观察的。 这意味着Java编译器可以某种方式找到此编译单元并解析/编译其内容。
2)如果任何独立于其属性的编译过程都可以找到并解析/编译此编译单元,则编译单元始终是可观察的。 通常,可以观察的编译单元由Java实现者提供。
3)当且仅当该包的至少一个编译单元可观察时,才能观察到包 或者至少存在一个可观察的子包。 另外我想要注意的是,包仍然可以包含不可观察的编译单元或子包。
4)当且仅当存在至少一个始终可观察到的此包的编译单元时,才能始终观察包。 或者至少存在一个始终可观察的子包。 通常可观察的子包由Java实现者提供。 另外我想要注意的是,包仍然可以包含不可观察的编译单元或子包。
答案 1 :(得分:0)
这是我之前回答的延续。
让我们考虑以上四个概念如何与" Java SE 8"的实现相关联。来自Oracle。
首先,编译单元是简单文件,包是本地文件系统的文件夹。
1)我们如何使特定的编译单元可以观察到特别的恭维? 为此,我们使用Java Compiler javac并枚举Compilation Inits,用空格分隔它们。
例如,如果当前文件夹是D:\ Foo1 \ Foo2,我们写
javac com \ myclass1 \ MyClass1.java com \ myclass2 \ MyClass2.java
我们编译两个编译内容: d:\ Foo1 \ foo2的\ COM \ MyClass1的\ MyClass1.java d:\ Foo1 \ foo2的\ COM \ myclass2 \ MyClass2.java
我们也可以使用以下选项修改我们的编译: 1)" -sourcepath" javac编译器的选项。 2)" -classpath"或" -cp" javac编译器的选项。 3)" CLASSPATH"环境变量。
参见http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javac.html 了解更多详情。
我还要注意" -sourcepath"仅搜索编译单元,但" -classpath" (或-cp"和" CLASSPATH")不仅可以搜索编译单元,还可以搜索编译的Java类(* .class文件),这些类可以选择捆绑在jar / zip文件中。 这个编译的类现在不是编译单元,但在编译之前它们是编译单元。 我们可以将它们视为"修改"先前执行某些过程的编译单元或编译单元。 因此,通过上面的三个选项,我们可以为我们的特定编译添加更多的编译单元。
2)始终可观察的编译单元与" Java SE 8"的安装捆绑在一起。并位于" ... \ jdk1.8.0_51 \ jre \ lib"。 他们中的大多数被放置在众所周知的" rt.jar"。但是放在其他罐子里的编译单元也总是可以观察到的。 正如您所看到的,它们被捆绑为位于jar文件中的已编译类文件,因此它们被修改为#34;编制单位。
3)如果你看一下" ... \ jdk1.8.0_51 \ jre \ lib"你会发现很多总是可以观察到的包裹:
java - 根据规范始终可观察
java.lang - 根据规范
始终可观察java.io - 根据规范始终可观察
java.applet中
java.awt中
java.beans中
的java.math
java.net
java.nio中
java.rmi中
java.security
的java.sql
java.text中
java.time
java.util中
.........
此外,您可以将自己的库放入" ... \ jdk1.8.0_51 \ jre \ lib \ ext"为了你的libs总是可以观察到的。