Java包

时间:2020-01-09 10:36:54  来源:igfitidea点击:

Java包是一种将彼此相关的Java类分组为同一"组"(包)的机制。当Java项目(例如应用程序或者API)变大时,将代码拆分为多个Java类,然后将这些类拆分为多个Java包很有用。将类划分为多个Java包时,可以更轻松地确定我们要查找的某个类的位置。

Java包就像文件系统中的目录。实际上,磁盘上的软件包是一个目录。属于同一包的类的所有Java源文件和类文件都位于同一目录中。

Java软件包可以包含子软件包。 Java包因此可以构成所谓的包结构。 Java包结构类似于目录结构。它是这些类中的包,子包和类的树。 Java包结构确实组织为硬盘驱动器上的目录或者zip文件(JAR文件)内的目录。

子程序包的完整路径是其名称,所有祖先程序包名称都位于其前面,并以点分隔。例如,"导航"子包的完整路径为:

com.Hyman.navigation

同样,Java类的完全限定名称包括其程序包名称。例如," Page"类的完整限定名称是:

com.Hyman.navigation.Page

创建Java包结构

要创建Java包,必须首先在硬盘上创建源根目录。根目录本身不是包结构的一部分。根目录包含所有需要进入包结构的Java源代码。

创建源根目录后,即可开始向其添加子目录。每个子目录对应一个Java包。我们可以在子目录中添加子目录以创建更深的包结构。

将类添加到包中

为了将Java类添加到包中,我们必须做两件事:

  • 将Java源文件放在与要放入该类的Java包匹配的目录中。
  • 将该类声明为包的一部分。

将Java源文件放在与包结构匹配的目录结构中非常简单。只需创建一个源根目录,然后其中为每个包和子包递归创建目录。将类文件放入与我们要添加到的包匹配的目录中。

将Java源文件放入正确的目录(与该类应属于的包匹配)后,我们必须在该类文件中声明它属于该Java包。这是在Java源文件中声明包的方式:

package com.Hyman.navigation;

public class Page {
    ...
}

上面代码的第一行(粗体字)是声明类Page属于包com.Hyman.navigation的内容。

Java包命名约定

Java软件包始终以小写字母书写。与Java类不同,Java类的首字母通常是大写字母。

为避免使用与其他公共Java软件包相同的名称创建软件包,建议我们使用公司的反向域名来启动软件包层次结构。例如,因为我公司的域名是Hyman.com,所以我应该从一个名为com.Hyman的包结构开始。换句话说,一个名为" com"的顶级软件包,其内部的一个子软件包称为" Hyman"。

从其他Java包导入类

如果类A需要使用类B,则必须在类A内引用类B。如果类A和B位于同一Java包中,则Java编译器将接受两个类之间的引用。这是一个例子:

public class B {

    public void doIt() {
        // do something...
    }
}
public class A {

    public static void main(String[] args){
        B theBObj = new B();

        b.doIt();
    }
}

如果类A和B位于同一Java包中,则上面的代码没有问题。但是,如果类A和类B位于不同的Java包中,则类A必须导入类B才能使用它。看起来是这样的:

import anotherpackage.B;

public class A {

    public static void main(String[] args){
        B theBObj = new B();

        b.doIt();
    }
}

这是示例中的第一行,导入了类B。该示例假定类B位于名为" otherpackage"的Java包中。

如果类B位于" anotherpackage"的子包中,则必须列出到类B的完整包和子包路径。例如,如果类B位于" anotherpackage.util"包中,则import语句将像这样:

import anotherpackage.util.B;

从另一个包导入所有类

如果我们需要使用某个Java包中的许多类,则一次导入一个类会产生很多import语句。可以使用\而不是类名来导入包的所有类。这是一个这样的导入语句的外观:

import anotherpackage.util.*;

通过完全合格的班级名称使用班级

可以使用另一个包中的类,而无需使用import语句将其导入。我们可以编写完全限定的类名称,而不仅仅是类本身的名称。完全限定的类名包括完整的包路径,直达包含该类的子类,还包括类名本身。完全限定的类名也是我们在import语句中所写的名称。例如:

anotherpackage.util.TimeUtil;

我们可以使用此完全限定的类名称来引用另一个类中的TimeUtil类,如下所示:

public class A {

    public static void main(String[] args){
    
        anotherpackage.util.TimeUtil timeUtil = 
            new anotherpackage.util.TimeUtil();

        timeUtil.startTimer();
    }
}

如何将班级分为套餐

我们可能想知道如何决定要创建哪些Java包,以及如何将类划分为这些包。没有官方标准,但是有两种常用方法。

按层划分

第一种方法是在类所属的应用程序的"层"之后划分类。例如,应用程序可能具有数据库层。然后,我们将创建一个"数据库"包。与数据库通信所涉及的所有类都将位于"数据库"包中。

按应用程序函数划分

第二种方法是根据类别属于应用程序函数的哪一部分来划分类。因此,如果应用程序具有计算退休金的函数区域,则可以创建一个名为pension的Java包。养老金计算中以一种或者另一种方式涉及的所有类别都将进入该程序包(或者子程序包,如果"养老金"中的类别数量增加)。

结合我的域名,pension软件包的软件包结构为:

com.Hyman.pension

总共三个软件包,其中两个嵌套在其他软件包内(在" com"内部的" Hyman"和在" Hyman"内部的" pension")。

随着应用程序类数量的增加,将类划分为Java包的"按应用程序划分函数"方法往往比"按层划分"效果更好。我们将获得数量越来越多且内部具有较少类的应用程序函数包,而不是使用数量不断增加的类包,而不是使用数量固定的层包。 "按应用程序函数划分"是我使用的方法,也是我大多数同事所使用的方法。

内置Java包

Java平台附带了许多内置的Java软件包。这些软件包包含用于程序员经常需要的各种目的的类,例如从本地硬盘读取和写入文件,通过网络和Internet发送和接收数据,连接数据库以及许多其他事情。