之前对package等语句的了解并不是很深,今天借此机会,用这篇博文,好好梳理一下关于 Java 的包,和Java 的 package 等语句的有关知识:
// 啰嗦一句,在 DOS 下编译运行带有包语句的程序,更有利于对 包的相关语句的理解噢!~
1. package语句
通过关键字package声明包语句。
package 语句作为Java源文件的第一条语句,指明该源文件定义的类所在的包。package语句的一般格式为:
package 包名;
如果源程序中省略了package语句,源文件中所定义命名的类被隐含地认为是无名包的一部分,即源文件中定义命名的类在同一个包中,但该包没有名字。
包名可以是一个合法的标识符,也可以是若干个标识符加“.”分割而成,如:
package sunrise;
package sun.com.cn;
程序如果使用了包语句,例如:
package tom.jiafei;
那么目录结构必须包含有如下的结构…\tom\jiafei
比如c:\1000\tom\jiafei
并且要将源文件编译后得到的全部字节码文件拷贝到目录c:\1000\tom\jiafei中,如果事先将源文件保存到c:\1000\tom\jiafei中,然后编译源文件,那么生成的字节码文件就直接保存到当前目录中了,如:
c:\1000\tom\jiafei\javac 源文件
如果将名字为 Example 的源文件保存到c:\1000\tom\jiafei
然后编译原文件:
c:\1000\tom\jiafei\javac Example.java
运行程序时必须到tom\jiafei的上一层目录1000中来运行,如:
c:\1000\java tom.jiafei.Example
因为起了包名,类Example的全名已经是:tom.jiafei.Example(就好比大连的全名是:“中国.辽宁.大连”)
包名应该避免与其他包名冲突。
Sun公司建议大家使用自己所在公司的Internet域名倒置后做包名,例如,将域名“sina.com.cn”的倒置“cn.com.sina”做包名。
总结一下:
在使用 package 语句以后,要注意,如果在 DOS 下运行,运行程序时,必须找到包名的上一层目录,并在这一层目录来运行
2. 参数“–d”编译源文件
javac 可以使用参数-d指定生成的字节码文件所在的目录。如果不使用参数-d,javac在当前目录生成字节码文件。
如果源文件没有包名,使用参数-d可以将字节码文件存放到你指定的有效目录中,例如:
javac –d F:\tsinghua\1000 MyFile.java
将源文件MyFile.java生成的全部字节码文件存放到F:\tsinghua\1000。
如果源文件使用包语句声明了包名,使用参数-d时要格外小心。假设源文件的包名是tom.jiafei,保存在在D:\2000中,
下述编译命令:
D:\2000\javac –d F:\tsinghua\1000 MyFile.java
会在F:\tsinghua\1000目录下新建子目录结构tom\jiafe并将字节码文件存放到F:\ tsinghua\1000\tom\jiafei中。
而下述编译命令:
D:\2000\javac –d . MyFile.java
会在当前目录2000下新建子目录结构tom\jiafei,并将字节码文件存放到D:\2000\tom\jiafei中。
3. import 语句
使用import 语句可以引入包中的类
3.1 .使用类库中的类
为了能使用Java提供给我们的类,我们可以使用import语句来引入包中类。在一个Java源程序中可以有多个import语句,它们必须写在package语句(假如有package语句的话)和源文件中类的定义之间.
如果使用import语句引入了整个包中的类,那么可能会增加编译时间。但绝对不会影响程序运行的性能。
3.2.使用自定义包中的类
//这部分有些难,但是挺重要,很有必要仔仔细细弄懂
//我当时做实验时,就因为一知半解,查了许多资料,最后才发现,老师的 PPT 里,分明已经说得清清楚楚了 (当时的心情真是...踏破铁鞋无觅处,得来全不费工夫,但是真是十分自责和惭愧,要是我做实验前,先好好看看老师的资料,也就不用浪费那么久时间,在网上找资料了 T^T)
//因而整理出这篇博文,这样下次自己要找时,一下子就能找到,也就方便复习了
我们也可以使用import 语句引入自定义包中的类。如:import tom.jiafei.*;我们也可以对单独的一个类进行 编译,生成字节码文件然后供其它类使用。
假设源文件SquareEquation.java只有一个类组成,这个类可以被其它的程序引入使用,该源文件的包名是tom.jiafei。
为了使程序能使用tom.jiafei包中的类,我们必须在 classpath中指明我们包的位置,假设tom.jiafei的位置是:c:\2000,即在c:\2000下有子目录tom\jiafei。更新classpath的设置,在命令行执行如下命令:
set classpath=E:\jdk1.5\jre\lib\rt.jar;.;c:\2000 //简单说,就是在原来的 classpath 后面,加上 包tom\jiafei 的上一层目录,也就是加上c:\2000
总结一下:
就是需要在 classpath后面,再加上 包名所在位置的上一层目录
也可以将上述命令添加到Classpath值中。在Windows2000系统中,右击“我的电脑”,弹出快捷菜单,然后选择“属性”命令,弹出“系统特性”对话框,再单击该对话框中的高级选项,然后单击“环境变量”按钮。对于Win9x系统可以将上述命令写到autoexec.bat文件中。
将下述源文件SquareEquation.java编译得到的字节码文件拷贝到D:\ch4\tom\jiafei中。源文件保存在 D:\Ch4目录中,并用import 语句引入包tom.jiafei中的SquareEquation类。
3.使用无名包中的类
我们也可以使用无名包中的类。假如SquareEquation.java源文件中没有使用包语句,如果一个程序使用SquareEquation类,可以将该类的字节码文件存放在当前程序所在的目录中。
4.避免类名混淆
Java运行环境总是先到程序所在目录中寻找程序所使用的类,然后加载到内存。如果在当前目录没有发现所需要的类,就到import语句所指的包中查找。
当我们在一个源文件使用一个类时,只要不引起混淆,就可以省略该类的包名。但在某些特殊情况下就不能省略包名。
(1)区分无包名和有包名的类
如果一个源文件使用了一个无名包中的类,比如Triangle类,同时又用import语句引入了某个有包名的同名的类,就可能引起类名混淆。如果要同时使用tom.jiafei包中的Triangle类和无名包中的Triangle类,就不能省略包名,下面这两种情况都正确。
Triangle a1=new Triangle ();
tom.jiafei.Triangle a2=new tom.jiafei.Triangle ();
(注意:没有使用import语句)
import tom.jiafei.*;
Triangle a1=new Triangle ();
tom.jiafei.Triangle a2=new tom.jiafei.Triangle ();
需要注意的是:
import tom.jiafei.Triangle;
Triangle a1=new Triangle ();
tom.jiafei.Triangle a2=new tom.jiafei.Triangle ();
在这种情况下,a1和a2都是tom.jiafei.Triangle类的对象。
(2)区分有包名的类
如果一个源文件引入了两个包中同名的类,那么在使用该类时,不允许省略包名。
tom.jiafei.AA rose=new tom.jiafei.AA();
sun.com.AA rose=new sun.com.AA();