一个Java编译问题-package与classpath

死线 发布于

今天在补Java的时候突然出现了一个编译问题,困扰了我好久。

遇到的问题

现在我有两个java源文件,每一个文件定义了一个类。假设源文件为 A.javaB.java,唯一的类与文件同名,其中类B使用了A的类定义。此时由于我在两个类中都引用了第三方的包,比如c.jar包,c.jar包放在当前目录,这时候该如何编译?

一开始我用了如下的命令:

1
javac -cp c.jar B.java

结果如你所料,它提示我找不到A类的符号,奇了个怪?说好的放在同一个目录下会自动编译呢,然后我自作聪明的先将A类编译完毕之后再去编译B类,结果还是同样的错误,我勒个去,这咋回事?

我痛定思痛,难道是路径的问题?此时刚好我的两个类文件都放在…/yu/这个目录下,然后我强制在两个源文件的顶部加上了package限定

1
package yu;

这下总该行了吧,编译一下,得嘞,还是同样的错,醉了 ==!

解决方法

最后再仔细想想,是不是我在-cp指定第三方包的位置的时候默认的当前规则消失了,试了一下,果然如此,增加一个-cp参数即可

1
javac -cp c.jar;.\ B.java

我很好奇的在两个源文件首部再次加上了 package yu; 发现又编译不通过了,然后将cp的.\当前目录改成上级目录即可..\

总结

由上面的问题可以看出来,指定的-cp参数的唯一作用就是让package去找这些目录下指定的包名,所谓的需找外部包的过程,就是多叉树的一个查找过程。

有人可能将packageimport搞混,总结一下:

  • import的作用只是为了缩短字面值的长度(只是为了书写和观看方便,编译器会自动扩展查找路径)
  • package才起做真正的导入作用
  • 误认为import有导入功能的原因,一是因为import这个词有误导性,二是因为大部分包已经在默认的classpath路径下了
  • import相当于C++中的use, package才是namespace