包的定义
- 在笔者看来,包其实就是一个 文件夹,包含者我们定义的功能相似或相关的类、接口、枚举和注释,可以看成一种特殊的封装。
- 一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。
- 包的作用:防止命名冲突,访问控制,提供搜索和定位类(
class
)、接口(interface
)、枚举(enumerations
)和注释(annotation
)等。
包的创建(package)
包的创建需要使用package
关键词,在源文件的第一行进行声明。需要注意的是,每个源文件只能有一个包声明。
package com.sun.test;
包的命名规范
本部分内容参考该博客
Java的包名都有小写单词组成,应该避免使用与系统发生冲突的名字,如java.lang、java.swing等。多数开发人员采用自己公司在互联网上的域名称作为自己程序包的唯一前缀(如上例)。
个人和组织包命名规则如下:
indi :个体项目,指个人发起,但非自己独自完成的项目,可公开或私有项目,copyright主要属于发起者。
包名为“indi.发起者名.项目名.模块名.……”。pers :个人项目,指个人发起,独自完成,可分享的项目,copyright主要属于个人。
包名为“pers.个人名.项目名.模块名.……”。priv :私有项目,指个人发起,独自完成,非公开的私人使用的项目,copyright属于个人。
包名为“priv.个人名.项目名.模块名.……”。onem :与“indi”相同,推荐使用“indi”。
team :团队项目,指由团队发起,并由该团队开发的项目,copyright属于该团队所有。
包名为“team.团队名.项目名.模块名.……”。com :公司项目,copyright由项目发起的公司所有。
包名为“com.公司名.项目名.模块名.……”。
空包
如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed
package)中。这也是为什么即使我们没有在源文件中使用import
,也能调用相同路径下的其他源文件。
包的导入(import)
不同包之间的导入
不同包之间的使用通常有以下3种方法——
- 使用全名
com.hyggge.Animal ani = new com.hyggge.Animal()
- 导入该类
import com.hyggge.Animal; public class Test { public static void main(String[] args) { Animal ani = new Animal(); }
- 导入整个包(使用通配符
*
)
import com.hyggge.*; public class Test { public static void main(String[] args) { Animal ani = new Animal(); }
注意点
- 如果两个包(
com.hyggge
和com.czh
)都有Animal
类,即使把两个包都导入,访问Animal
类时仍然需要使用全名
import com.hyggge.*; import com.czh.*; public class Test { public static void main(String[] args) { com.hyggge.Animal ani = new com.hyggge.Animal(); com.Animal ani = new com.czh.Animal(); }
- 使用通配符
*
并不意味者将把包下的类、接口等都导入,而是按需求导入,即“用则导,不用则不导”。
有包的类和无包的类互相访问
有包的类和无包的类互相访问有以下规则:
- 无包的类可以访问有包的类, 直接导入即可;
- 有包的类无法访问无包的类, 直接访问是找同一个包中的, 由于不同包需要导入, 而无包的类无法导入(包的类属于无名包);
- 在定义类的时候, 为了让别人都能使用到, 所以一定要定义一个包。
包的无等级性
例如我们现在有两个包com.hyggge
和com.hyggge.czh
。从路径上看,这两个包时有等级的,但是实际上包和包之间没有包含关系。当需要使用这两个包中的类时,需要同时导入——
impot com.hyggge.*;
impot com.hyggge.czh.*;
静态导入
当我们需要频繁的访问某个类的常量或静态方法时,可以采用静态导入,即使用import static
将类中的常量和静态方法导入。见下例(摘自该博客)
import static java.lang.Math.PI;
import static java.lang.Math.cos;
public class ImportTest {
public static void main(String[] args) {
double r = Math.cos(Math.PI * 2);
double r1 = Math.cos(PI * 2);
double r2 = cos(PI * 2);
System.out.println(r+" "+r1+" "+r2);
}
}
也可以使用通配符
*
import static java.lang.Math.*;
包的路径
包的中java源文件的目录和编译后class文件的目录应该和包的名字对应起来,但是并不要求两者路径一样,可以分开来安排。如下所示——
<path-one>\sources\com\runoob\test\Runoob.java <path-two>\classes\com\runoob\test\Google.class
类的目录的绝对路径叫做
class path
。设置在系统变量CLASSPATH
中。编辑器和java虚拟机将package
名字加到class path
后来构造 .class 文件的路径设置CLASSPATT系统变量,方法见该博客
如果我们的文件都在运行目录下时,也可以不设置
CLASSPATH
。也就是说在没有配置CLASSPATH
环境变量时,java命令在找class文件时是默认在当前目录下寻找的。