Java包和类路径问题

标签 java

任何人都可以解释以下问题的答案:

给定一个正确编译的类,其源代码是:

 package com.sun.test;
 public class Commander {
  public static void main(String[] args) {
  }
 }

假设类文件位于/foo/com/sun/test/,当前目录为/foo/,类路径包含“.” (当前目录)。哪个命令行正确运行 Commander?

一个。 Java指挥官

B. java com.sun.test.Commander

C. java com/sun/test/Commander

D. java -cp com.sun.test 指挥官

E. java -cp com/sun/test 指挥官

最佳答案

最好的答案是 B。C 也适用于某些平台,但不推荐并且非常不常见(至少,我在 Java 编程的 10 多年中从未见过它)。


编辑

Java 初学者的一个常见误解是类名类似于“MyClass”。但这并不准确;在声明 class MyClass 中看到的命名法“MyClass”确实为程序员提供了便利,编译器将其与包声明相结合以创建 Java 所指的合格类名,所有类名真的是运行时。 (在 C# 中,他们为此使用 namespace )。

这在许多情况下变得非常明显,例如始终包含 java.lang.String 的堆栈跟踪和方法签名。因为“String”只是解析为java.lang.String 的缩写形式。您可以通过在自己的包中创建自己的 String 来证明这一点……但请注意,这样做将要求您在导入包或类的任何地方显式使用 java.lang.String 或 my.package.String。

一旦您理解了所有类名都是完全限定的这一事实,并且编译器通过使用导入将短格式解析为完全限定的形式来帮助您避免繁琐的工作,事情就会变得更加清晰。

然后应该很明显为什么:

java -cp com/sun/test 指挥官

没用。 cp 选项将目录 ./com/sun/test(相对于当前目录)放在类路径中,但没有名为 Commander 的类...它是 com.sun.test.Commander。这意味着两件事:(a) 命令行需要 com.sun.test.Commander 和 (b) 类路径必须包含包含“com”的目录的条目才能解析此类,因为名为 x.y.MyClass 的类必须在相对于某些类路径元素的 x/y 中。


PS:除非您受雇于 Sun,否则您不应该使用 com.sun 作为包名,因为域名 sun.com 属于 Sun。存在此约定是为了避免类打包和命名冲突。


PPS:有默认包这样的东西,它是通过省略包声明来“指定”的——但它几乎不应该被使用。我发现的一个合法的地方是一个独立的“启动器/类加载器”,它希望能够做到:

java -cp . Launcher com.xxx.yyy.TargetApp

当前目录中有 Launcher.class... 这只是因为 JAR 文件在应用程序运行时保持锁定状态,而类文件则没有,这意味着 Launcher.class 可以 self 更新,而 Launcher.jar不能。

关于Java包和类路径问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2294733/

相关文章:

java - 将表单数据从 PDF 传递到 iText 中的 servlet

java - 如何使用spring aop自动设置date_created

java - GWT Java - "getWidget()"已弃用 - 什么取代了它?

java - 如何使 java.util.Date 线程安全

java - 为什么 Date 对象不代表我的 JVM 时区中的日期?

java - 将数据从互联网加载到 ListView 的最合适方法

java - MongoDB 太多打开的连接

java - Android:使用onDoubleTap画圆

java - Google-App-Engine (Struts2) 中的资源包

java - Windows安装Java 11 OpenJDK(系统路径问题)