Java包


在Java中使用包是为了防止命名冲突,简化类、接口、枚举和注释的查找和使用。

Package可以定义为提供访问保护和名称空间管理的相关类型(类,接口,枚举和注释)的组合。

现有的一些java包:

  • java.lang:包含java语言的基础类

  • java.io:包含输入、输出功能的相关类

程序员可以定义自己的程序包来捆绑类、接口等,将实现的相关类分组是一种好习惯,这样程序员就可以轻松确定类、接口、枚举和注释是否相关。

由于该程序包创建了一个新的命名空间,因此不会与其他程序包中的名称发生任何名称冲突。因此使用包可以更轻松地提供访问控制,也可以更轻松地找到相关的类。

创建一个包


在创建包时应该为包选择一个名称,并在每个用到该包的源文件顶部写上这个包的import声明。

package语句应位于源文件的第一行,每个源文件中只能有一个package语句。

如果未使用package语句,则类、接口、枚举和注释类型将放置在当前默认包中。

要使用package语句编译Java程序,必须使用-d选项,如下所示。

javac -d Destination_folder file_name.java

然后在指定的目录创建一个带有给定包名的文件夹,编译后的类文件将被放在该文件夹中。

让我们看一个创建名为 animals 包的例子,包名通常使用小写字母声明,以避免与类和接口的名称发生冲突。

以下的例子包含 animals 接口:

/* 文件名 : Animal.java */
package animals;

interface Animal {
    public void eat();
    public void travel();
}

现在,让我们在同一包中实现上述接口 animals :

package animals;
/* 文件名 : MammalInt.java */

public class MammalInt implements Animal {

    public void eat() {
        System.out.println("Mammal eats");
    }

    public void travel() {
        System.out.println("Mammal travels");
    }

    public int noOfLegs() {
        return 0;
    }

    public static void main(String args[]) {
        MammalInt m = new MammalInt();
        m.eat();
        m.travel();
    }
}

现在,如下所示编译java文件:

$ javac -d . Animal.java 
$ javac -d . MammalInt.java

现在一个名为animals的文件夹将在当前目录中创建,并将这些类文件放置在其中。

可以在包中执行类文件并获取结果,如下所示:

Mammal eats
Mammal travels

import关键字


如果一个类想在同一包中使用另一个类,则无需使用包名。

在这里,Boss类被添加到已经包含Employee的payroll包中。然后,Boss可以在不使用payroll前缀的情况下引用Employee类,如下所示:

package payroll;
public class Boss {
    public void payEmployee(Employee e) {
        e.mailCheck();
    }
}

如果Employee类不在payroll包中,该怎么办?Boss类可以使用以下技术之一来引用其他程序包中的类:

  • 可以使用该类的完全限定名称,例如:

payroll.Employee
  • 可以使用import关键字和通配符(*)导入软件包,例如:

import payroll.*;
  • 可以使用import关键字导入类本身,例如:

import payroll.Employee;

注意:一个类文件可以包含任意数量的import语句,import语句必须出现在package语句之后和类声明之前。

软件包的目录结构


将一个类放在包中会产生两个结果:

  • 包的名称成为类名称的一部分,正如我们在上一节中所讨论的;

  • 包的名称必须与相应字节码所在的目录结构匹配。

这是使用Java管理文件的简单方法:

将类、接口、枚举或批注类型的源代码放在文本文件中,该文件的名称为该类的名称,其扩展名为.java.

//文件名:Car.java
package vehicle;

public class Car {
    //类的实现。
}

现在,将源文件放在一个目录中,该目录的名称反映该类所属的软件包的名称:

....\vehicle\Car.java

现在,正确的类名和路径名如下:

  • 类名→vehicle.Car

  • 路径名→vehicle \ Car.java(在Windows中)

通常,公司使用其反向Internet域名作为其程序包名称。

例如:公司的Internet域名是apple.com,则其所有程序包名称都将以com.apple开头,软件包名的每个组成部分都对应一个子目录。

例如:该公司有一个com.apple.computers软件包,其中包含Dell.java源文件,它将包含在一系列子目录中,如下所示:

....\com\apple\computers\Dell.java

在编译时,编译器会为其中定义的每个类、接口和枚举创建一个不同的输出文件。输出文件的名称是类的名称,其扩展名是.class.

例如:

//文件名:Dell.java
package com.apple.computers;

public class Dell {
}

class Ups {
}

现在,使用-d选项如下编译该文件:

$javac -d . Dell.java

这些文件将被编译如下:

.\com\apple\computers\Dell.class
.\com\apple\computers\Ups.class

可以通过下面的方式,导入所有在\com\apple\computers\中定义的类或接口:

import com.apple.computers.*;

与.java源文件一样,已编译的.class文件应位于反映软件包名的一系列目录中。但是,.class文件的路径不必与.java源文件的路径相同,可以将源目录和类目录分开排列,如下所示:

<path-one>\sources\com\apple\computers\Dell.java

<path-two>\classes\com\apple\computers\Dell.class

通过这样做,可以在不透露源代码的情况下将访问class目录的权限授予其他程序员,还可以以这种方式管理源文件和类文件,以便编译器和Java虚拟机(JVM)可以找到程序使用的所有类型。

类目录的完整路径,<path-two>\classes,被称为类路径,并通过CLASSPATH系统变量设置,编译器和JVM都是通过在类路径添加包名来构造你的.class文件的路径。

假设<path-two>\classes是类的路径,包的名称是com.apple.computer,那么编译器和JVM将在<path-two>\classes\comapple\computers中寻找.class文件。

一个类路径可以包括几个路径,多个路径应以分号(Windows)或冒号(Unix)分隔。默认情况下,编译器和JVM搜索当前目录和包含Java平台类的JAR文件,以便这些目录自动位于类路径中。

设置CLASSPATH系统变量


要显示当前的CLASSPATH变量,请在Windows和UNIX(Bourne shell)中使用以下命令:

  • 在Windows→C:\>设置CLASSPATH

  • 在UNIX中→%echo $ CLASSPATH

要删除CLASSPATH变量的当前内容,请使用:

  • 在Windows→C:\>设置CLASSPATH =

  • 在UNIX中→%unset CLASSPATH;导出CLASSPATH

设置CLASSPATH变量:

  • 在Windows中→设置CLASSPATH = C:\ users \ jack \ java \ classes

  • 在UNIX中→%CLASSPATH = / home / jack / java / classes;导出CLASSPATH