访问权限控制的理解一
访问控制(或隐藏具体实现)与“最初的实现并不恰当”有关。
Java提供了访问权限修饰词,访问权限控制的等级,从最大权限到最小权限依次为:public、protected、包访问权限(没有关键词)和private。
1、包:库单元
包内包含有一组类,它们在单一的名字空间之下被组织在了一起。
当编写一个Java源代码文件时,此文件通常被称为编译单元(有时也被称为转译单元)。每个编译单元都必须有一个后缀名.java,而在编译单元内则可以有一个public类,该类的名称必须与文件的名称相同(包括大小写,但不包括文件的后缀名.java)。每个编译单元只能有一个public类,否则编译器就不会接受。如果在该编译单元之中还有额外的类的话,那么在包之外的世界是无法看见这些类的,这是因为它们不是public类,而且它们主要用来为主public类提供支持。
一、代码组织
当编译一个.java文件时,在.java文件中的每个类都会有一个输出文件,而该输出文件的名称与.java文件中每个类的名称相同,只是多了一个后缀名.class。因此,在编译少量.java文件之后,会得到大量的.class文件。如果用编译型语言编写过程序,那么对于编译器产生一个中间文件(通常是一个obj文件),然后再与通过链接器(用以创建一个可执行文件)或类库产生器(librarian,用以创建一个类库)产生的其他同类文件捆绑在一起的情况,可能早已司空见惯。但这并不是Java的工作方式。Java可运行程序是一组可以打包并压缩为一个Java文档文件(JAR,使用Java的jar文档生成器)的.class文件。Java解释器负责这些文件的查找、装载和解释。
类库实际上是一组类文件。其中每个文件都有一个public类,以及任意数量的非public类。因此每个文件都有一个构件。如果希望这些构件(每一个都有它们自己的独立的.java和.class文件)从属于同一个群组,就可以使用关键字package。
如果使用package语句,它必须是文件中除注释以外的第一句程序代码,在文件起始处写:package access;
就表示你在声明该编译单元是名为access的类库的一部分。或者换种说法,你正在声明该编译单元中的public类名称是位于access名称的保护伞下。任何相要使用该名称的人都必须使用前面给出的选择,指定全名或者与access结合使用关键字import。(请注意,Java包的命名规则全部使用小写字母,包括中间的字也是如此。)
身为一个类库设计员,很有必要牢记:package和import关键字允许你做的,是将单一的全局名字空间分割开,使得无论多少人使用Internet以及Java开始编写类,都不会出现名称冲突问题。
二、创建独一无二的包名
读者也许会发现,既然一个包从未真正将被打包的东西包装成单一的文件,并且一个包可以由许多.class文件构成,那么情况就有点复杂了。为了避免这种情况的发生,一种合乎逻辑的做法就是将特定包的所有.class文件都置于一个目录下。也就是说,利用操作系统的层次化的文件结构来解决这一问题。这是Java解决混乱问题的一种方式。
将所有的文件收入一个子目录还可以解决另外两个问题:怎样创建独一无二的名称以及怎样查找有可能隐藏于目录结构中某处的类。这些任务是通过将.class文件所在的路径位置编码成package的名称来实现的。按照惯例,package名称的第一部分是类的创建者的反顺序的Internet域名。域名是独一无二的,因此package名称也是独一无二的,也就不会出现名称冲突的问题了。
此技巧的第二部分是把package名称分解为你机器上的一个目录。所以当Java程序运行并且需要加载.class文件的时候,它就可以确定.class文件在目录上所处的位置。
Java解释器的运行过程如下:首先,找出环境变量CLASSPATH,CLASSPATH包含一个或多个目录,用作查找.class文件的根目录。从根目录开始,解释器获取包的名称并将每个句点替换成反斜杠,以从CLASSPATH根中产生一个路径名称。得到的路径会与CLASSPATH中的各个不同的项相连接,解释器就在这些目录中查找与你所要创建的类名称相关的.class文件。
如前所述,package语句必须是文件中的第一行非注释程序代码。
每一个文件的第一行注释都指定了该文件在源代码目录树中的位置。
如果沿此路径往回看,可以看到包的名称com.bruceeckel.simple,但此路径的第一部分怎么办呢?它将由环境变量CLASSPATH关照,在我的机器上是:CLASSPATH=.;D:\JAVA\LIB;C:\DOC\JavaT
可以看到,CLASSPATH可以包含多个可供选择的查询路径。
但在使用JAR文件时会有一点变化。必须在类路径中将JAR文件的实际名称写清楚,而不仅是指明它所在位置的目录。
三、定制工具库
将有用的新工具添加到自己的类库中。
四、用import改变行为
Java没有C的条件编译功能,该功能可以使你不必更改任何程序代码,就能够切换开关并产生不同的行为。Java去掉此功能的原因可能是因为C在绝大多数情况下是用此功能来解决跨平台问题的,即程序代码的不同部分是根据不同的平台来编译的。由于Java自身可以自动跨越不同的平台,因此这个功能对Java而言是没有必要的。
然而,条件编译还有其他一些有价值的用途。调试就是一个很常见的用途。调试功能在开发过程中是开启的,而在发布的产品中是禁用的。可以通过修改被导入的package的方法来实现这一目的,修改的方法是将你程序中用到的代码从调试版改为发布版。这一技术可以适用于任何种类的条件代码。
五、对使用包的忠告
务必记住,无论何时创建包,都已经在给定包的名称的时候隐含的指定了目录结构。这个包必须位于其名称所指定的目录之中,而该目录必须是在以CLASSPATH开始的目录中可以查询到的。最初使用关键字package,可能会有一点不顺。注释掉可以试试。
注意,编译过的代码通常放置在与源代码的不同目录中,但是必须保证JVN使用CLASSPATH可以找到该路径。

浙公网安备 33010602011771号