java学习笔记:包

=============================================

package的基本概念

包(package)定义了软件单元,它能够独立发布,并能够与其他包组成应用程序。包的成员是一些关联的类、接口以及子包,也可以包含包中的类所使用的附加资源文件(如图像文件)。

包的主要作用为:
(1)包将相互管理的接口和类组合成组;
(2)包创建了命名空间来避免类型之间的命名冲突;
(3)包机制为开发应用程序提供了保护域。

package和import是一对相辅相成的java关键字,这两个关键字允许我们做的事情就是分割单个全局命名空间。

=============================================

package使用示例

以下是一个使用package的示例:


package attr;

说明:

(1)package语句必须作为文件的第一个非注释语句出现。

(2)这条语句声明了在此文件中定义的所有类和接口都是attr包的一部分。

(3)包中含有的每种类型名都隐式的加上了包名前缀。

pakcage的命名规定

(1)名字内的所有字母都应小写。

(2)包的命名一般采取Internet域名的反序排列,以下是一个示例:com.darkmi.attr

=============================================

如何使用被打包的类及接口

当你所写的包外代码需要使用包内声明的类型时,有两种选择:

(1)使用类型的完全限定名。以包名作为前缀的类型名字叫做类型的完全限定名(fully qualified name)。例如,String类的完全限定名是java.lang.String。

(2)将包的部分或者全部内容导入(import)。

import有两种方式:

(1)按需导入(import on demand),示例:import com.darkmi.*;

(2)单一类型导入(single type import),示例:import com.darkmi.Test;

import机制是一种被动机制,因为关于有名包的信息和类型信息并不是在编译时被读入加载的,而是直到包中的某个类型被使用时才读入这些信息。import语句只是简单的告诉编译器,当它在本地找不到定义的类型时,它应如何确定类型的完全限定名。

当我们需要导入位于不同package中的同名的类型时,可以按如下方式解决:

(1)全部使用类型的完全限定名,举例如下:


public void test(){
com.darkmi.MyMath.add();
com.redmi.MyMath.add();
}

(2)
仅仅import其中一个,另外一个则使用完全限定名,举例如下:

import com.darkmi.MyMath;
public class Test{
public static void test(){
MyMath.add();
com.redmi.MyMath.add();
}
}

=============================================

包内代码的可访问性

为Java创建一个源码文件的时候,它通常叫作一个“编辑单元”(有时也叫作“翻译单元”)。每个编译单元都必须有一个以.java结尾的名字。而且在编译单元的内部,可以有一个公共(public)类,它必须拥有与文件相同的名字(包括大小写形式,但排除.java文件扩展名)。如果不这样做,编译器就会报告出错。每个编译单元内都只能有一个public类(同样地,否则编译器会报告出错)。那个编译单元剩下的类(如果有的话)可在那个包外面的世界面前隐藏起来,因为它们并非“公共”的(非public),而且它们由用于主public类的“支撑”类组成。

编译一个.java文件时,我们会获得一个名字完全相同的输出文件;但对于.java文件中的每个类,它们都有一个.class扩展名。因此,我们最终从少量的.java文件里有可能获得数量众多的.class文件。

如果没有为类成员指定访问指示符,那么该类成员的访问权限称为“友好”(Friendly)访问。这意味着当前包内的其他所有类都能访问“友好的”成员,但对包外的所有类来说,这些成员却是“私有”(Private)的,外界不得访问。包括该包内的子包的类也不能访问。

由于一个编译单元(一个文件)只能从属于单个包,所以单个编译单元内的所有类相互间都是自动“友好”的。因此,我们也说友好元素拥有“包访问”权限。

在声明包内顶级接口和类的可访问性时,有两种选择:

(1)包内可访问:没有public修饰符的类型具有包的作用域,它们对于相同包中的所有代码是有效的,但对于包外的代码,甚至子包内的代码都是隐藏的,不能访问的。

(2)全局可访问:使用public修饰的类和接口对包外的代码是可访问的。

没有被声明为public、protected、private的类成员是可以被包内的代码直接访问的,而对于包外的代码是隐藏的。标识符默认的访问修饰符是“package”,唯一例外的接口,其成员的默认访问修饰符是public。

=============================================

类的的搜索路径


//: List.java
// Creating a package
package com.bruceeckel.util;

public class List {
public List() {
System.out.println(
"com.bruceeckel.util.List");
}
} ///:~

这两个文件都置于我自己系统的一个子目录中:


C:\DOC\JavaT\com\bruceeckel\util

若通过它往回走,就会发现包名com.bruceeckel.util,但路径的第一部分又是什么呢?这是由CLASSPATH环境变量决定的。在我的机器上,它是:


CLASSPATH=.;D:\JAVA\LIB;C:\DOC\JavaT

可以看出,CLASSPATH里能包含大量备用的搜索路径。

然而,使用JAR文件时要注意一个问题:必须将JAR文件的名字置于类路径里,而不仅仅是它所在的路径。所以对一个名为grape.jar的JAR文件来说,我们的类路径需要包括:


CLASSPATH=.;D:\JAVA\LIB;C:\flavors\grape.jar

正确设置好类路径后,可将下面这个文件置于任何目录里:


//: LibTest.java
// Uses the library
package c05;
import com.bruceeckel.util.*;

public class LibTest {
public static void main(String[] args) {
Vector v = new Vector();
List l = new List();
}
} ///:~

编译器遇到import语句后,它会搜索由CLASSPATH指定的目录,查找子目录com\bruceeckel\util,然后查找名称适当的已编译文件(对于Vector是Vector.class,对于List则是List.class)。注意Vector和List内无论类还是需要的方法都必须设为public。

该部分内容来自《java编程思想第三版》

=============================================

此条目发表在java/j2ee分类目录,贴了, , , 标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据