【问题标题】:Are the imported packages included in the .class file after compilation?导入的包编译后是否包含在.class文件中?
【发布时间】:2016-11-13 17:38:54
【问题描述】:

JDK 中未包含的包(例如javax.websocket)需要下载并使用-cpCLASSPATH 环境变量引用才能导入(否则会出现编译错误包 X 不存在)。

编译后得到.class文件后,是否可以将这些文件传送到没有javax.websocket包的计算机上,让该计算机上的JVM运行它们,或者是否需要在两台计算机上都有该软件包?

换句话说:当你写import bar.foo;时,你实际上是在写“每次你看到foo,去这个位置看看它是什么。”。但是,当您编译完源代码后,字节码是否仍然说“去这个位置看看它是什么”,还是它已经去那个位置并“导入”了所有内容,以便不再需要该位置?

【问题讨论】:

  • 请注意,import 语句仅用于编译。他们在运行时什么都不做。见this answer。是的,如果你要使用一个类,它需要在运行时可用。
  • 你在运行时也需要外部库
  • @SotiriosDelimanolis 你是说如果 Java 设计者允许你在没有它们的情况下编译源代码,那么可以省略任何 import 语句,只要你确保包在运行时可用?
  • @Gendarme 它们的存在是为了让您可以使用简单的类型名称,不限定,即。没有他们的包名前缀。如果没有它们,您将不得不在任何地方使用完全限定名称。

标签: java compilation package


【解决方案1】:

编译后得到.class文件后,是否可以将这些文件转移到没有javax.websocket包的电脑上,让那台电脑上的JVM运行,还是必须要有两台电脑上的包?

必须在两台计算机上都有该软件包。字节码假定相关类将在运行时提供给 JVM。

此外,即使在同一台计算机上编译和运行也是如此:Java 编译器从其中提取包进行编译的位置可能与 JVM 在运行代码时从其中提取包的位置不同。

【讨论】:

  • “Java 编译器拉取其包进行编译的位置可能与运行代码时 JVM 拉取包的位置不同。”CLASSPATH 变量仅用于编译而不在运行时使用?那么,如何指定运行时拉包的位置呢?
  • @Gendarme javacjava 都将使用相同的 CLASSPATH 环境变量。但是,您可以通过将 -classpath 选项传递给编译器或 JVM 来覆盖它。根据 Oracle 的说法,这种指定类路径的方式优于使用 CLASSPATH 变量。
  • 请注意,import 语句实际上只是 FQCN 替换的编译时糖,在运行时无效。 e. G。导入ArrayList并使用它与编写完整的FQCN java.util.ArrayList相同。
【解决方案2】:

可以在 SO 上找到对该问题的非常详尽的解释:

直接引用作者JB Nizet:(添加斜体是我的)

编译类路径是用于编译 Java 源文件的类路径(使用 javac -cp ... 或您的 IDE)。源文件中引用的每个类都必须存在于 compile 类路径中,否则编译器会抱怨找不到该类。

一旦你编译了这些类,你就可以使用它们运行一个程序(使用java -cp ...)。显然,您的源代码直接依赖的库应该在 runtime 类路径中。但这还不是全部。如果你直接依赖CoolLibrary.jar,而这个库内部依赖Guava.jar,那么Guava.jar也必须在运行时类路径中,尽管编译时不需要它。

Webapps 有点特别。 [...原来的答案还在继续...]

【讨论】:

  • 最后一点很有趣。避免不必要耦合的另一个原因。
猜你喜欢
  • 2021-09-26
  • 2021-08-09
  • 2012-11-12
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
  • 1970-01-01
相关资源
最近更新 更多