Java包和类路径问题

时间:2010-02-19 07:37:37

标签: 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

℃。 java com / sun / test / Commander

d。 java -cp com.sun.test Commander

电子。 java -cp com / sun / test Commander

3 个答案:

答案 0 :(得分:4)

最好的答案是B. C也可以在某些平台上运行,但是不推荐使用并且非常罕见(至少,我在10年以上的编程Java中没有看到它)。


修改

Java中对初学者的一个常见误解是类名称类似于“MyClass”。但那不准确;在声明class MyClass中看到的术语“MyClass”对程序员来说真的很方便,编译器与包声明结合起来创建Java所指的合格类名,所有类名实际上都是运行。 (在C#中,他们使用命名空间)。

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

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

这应该是明显的原因:

java -cp com / sun / test Commander

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


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


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

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

在当前目录中使用Launcher.class ...这只是因为在应用程序运行时JAR文件被锁定而类文件不是,这意味着Launcher.class可以自我更新,而Launcher.jar不能。

答案 1 :(得分:2)

一个。不起作用,因为Java找不到Commander

B中。会工作,因为Java找不到com.sun.test.Commander

℃。至少在Windows平台上会起作用。这就是为什么你必须使用.而不是/

D和E.他们无法工作,因为我们仍然要求Java搜索课程Commander而不是com.sun.test.Commander

答案 2 :(得分:2)

假设未设置CLASSPATH环境变量(因此默认情况下当前工作目录位于类路径中),答案如下:

一个。不起作用,默认包中没有Commander类

B中。这个工作

℃。这个也适用,但B是首选

d。类路径是foo / com.sun.test,默认包中没有Commander类

电子。类路径是foo / com / sun / test,默认包中没有Commander类