Java包(package)

来源:互联网 发布:餐饮文案 知乎 编辑:程序博客网 时间:2024/05/16 09:19

Java中的包(package)将一组相关的类型(type)组织在一起,这里的type包括类class、接口interface、枚举类型enum、注释类型。枚举类型可以看成是特殊的class,而注释类型可以看成特殊的interface,所以一般说type就是class和interface。


包在概念上式一种抽象结构,在代码层次上面,如果要将某个type放进某个包,就在该type的最前面加入一条package语句。package语句的具体格式为:package package_name;关于包名在下文说明。在代码文件的结构上,属于同一个包的代码在相同的文件目录下。例如,在JDK中,有关Java的基础类型放在名为java.lang的包中,这些类型的代码文件都在...\java\lang\目录结构中。有关输入输出的type被组织在java.io包中。我们在写自己的代码的时候,也将我们的代码组织在各个包中,如果一个type中没有package语句,那它会组织到一个默认的包中。一般情况下都将自己的代码放进包中,除非是刚刚入门或者临时测试的代码。


那么为什么要使用包呢?至少有以下几个原因:

-- 让我们方便地知道在同一个package中的这些类型是相关的。

-- 便于找到需要的type在哪里。比如我要找输入输出的类型,很容易知道要在java.io中寻找。

-- 防止命名冲突。一旦使用包以后,类的全名将包括包名在内,不同程序员之间即使使用了相同的类名,加上自己的包名或就不会冲    突。另外也可以避免自己的类名与Java标准库中的类名冲突。

-- 包另外一个重要作用就是进行访问控制,如果一个类型或者它的成员没有显式声明访问修饰符(public、protected、private),    在类型的使用范围是其    所在的包。包外的类型都不能使用这个类型。


我们知道如果两个类不在同一个包中,那它们是允许有相同名字的,因为不同的包将使它们的完全限定名不同。更简单的说法,一个type由它的完全限定名来标识。即便如此,不同的程序员也有可能使用完全相同的包名,并在这个包中定义相同名字的类,有什么办法能有效解决这个命名冲突吗?因此,包的命名就存在一些惯例做法,例如,包名一般用全部小写字母,用于区分type。一般建议用域名的反序来命名java包,例如新浪的域名为sina.com.cn,那么新浪的程序员可以将包命名为cn.com.sina.mypackage。至于在同一个反序域名下还存在冲突,就需要协调了。Java语言本身的包用java或者javax开头。需要注意的是,一些域名可能是非法的包名,比如含有“-”、java关键字或者其他特殊字符,这时候建议将这些非法字符换成下划线。比如域名为test-name.com,报名可以是com.test_name,域名为example.int相应的包名int_.example遇到诸如123的,换成_123等等。

另外需要注意的是,包与包之间不存在层次结构,比如java.awt和java.awt.color这两个包,属于前者的type放在...\java\awt目录下,属于后者的type放在...\java\awt\color目录下,但是java.awt.color不包含在java.awt中,之所以这么命名只是为了让它们之间的关系更明显。因此,导入java.awt.*知识导入了java.awt包中的所有type,而不导入java.awt.color包中的type。


使用包中的成员(type)

如果想在包外使用这个包中的type,有以下几种方式:

1. 使用完全限定名,例如为了使用Arrays,创建对象的时候用new java.util.Arrays。

2. 导入想要的type。import java.util.Arrays; 导入之后就可以多次使用。

3. 导入包中所有类。import java.util.*; 

三种情况各有不同,使用时自行选择。为了方法,Java编译器自动导入了两个包(1)java.lang(2)当前包(包含该源码的包)。你肯定没有import java.lang.String过吧?当前包中的类也可以直接使用了,无需导入。另外,如果在同一个类中导入两个相同名字的类,此时必须使用完全限定名进行区分。


静态导入

如果你在类中需要频繁使用某个类的静态域或者静态方法,这时候可以考虑使用静态导入。例如java.lang.Math中的静态域PI。正常情况下,你这样使用Math.PI,但是如果你使用的次数十分频繁,你可能不想一直写Math,所以你首先import static java.lang.Math.PI; 然后你就直接使用PI就够了,其他cos函数、sin函数也一样,静态导入可以使得表达式更接近数学上的表达。将包中的全部静态成员一次性导入也是没有问题的:import java.lang.Math.*; 注意区分静态导入与一般的导入,一般的import是为了导入某个需要的type,而static import是为了使用类型中的静态域或者静态方法。静态导入需要十分谨慎地使用。

0 0
原创粉丝点击