被一个java新人请教关于包的理解和使用,想起了自己当年刚学java时候的体会。
包-Pakage,概念理解和使用不难,但对于刚接触java的人而言,有点抽象和不解。
人人皆知,java中的包主要用于解决类的重名问题,类似于XML、C#,PHP等命名空间的概念,但与这些语言有所区别,它既有命名空间的逻辑分割又有物理上的实际目录划分。
一.使用
pakage mosang.tech //表明A.java 源文件中,所有类都位于mosang.tech包中 public class A{ public static void main(String [] args){ new B().showInfo(); } } class B{ public showInfo(){ System.out.print("this a method of how to using pakage"); } }
假设我们已经将classpath设置为A.java所在的目录:
上述代码运行编译后会自动生成mosang/tech文件夹,同时得到一个B.class字节码文件位于tech文件夹中
javac -d . A.java
这时候,运行B.class文件需要带完整包名,哪怕我们在命令行窗口进入了mosang/tech目录。
java mosang.tech.B
这就是包的基本用法。
二.陷阱一:类名的使用
如果我们在命令行进入mosang/tech目录运行B.class,编译器会提示找不到文件,因为类的名字已是mosang.tech.B而不是B。
二.陷阱二:classpath路径与包名
JVM在加载带包名的路径时候,会先到classpath指定的目录,再从此按照包名结构去查找class文件。如果我们在命令行进入mosang/tech目录运行mosang.tech.B,同样会报错,因为此时的完整路径变成了classpath/mosang/tech/mosang/tech/B.class
三.陷阱三:包名与目录名
java中,包名必须经过程序中pakage语句来指定,而不是靠目录结构来指定的,是先有了包名,才需要相应的目录结构。我们来做个试验:
删除原生成的B.lass文件,在源代码A.java中,将pakage语句注释掉,重新编译得到B.class,将B.class拷贝到mosang/tech文件夹中,classpath目录下运行mosang.tech.B,会出错,因为此时的类名是B而不是mosang.tech.B。
所以,我们常常误以为把一个类文件放到了一个目录中,这个目录结构就自然成了包名,这就大错特错了。这点很多人包含有多年java经验的人都会犯错,绝大部分新手更是有这种自以为是理解。