Java - 包
Java中使用包是为了防止命名冲突、控制访问、使类、接口、枚举和注释的搜索/定位和使用更容易等。
一个包 可以定义为一组相关类型(类、接口、枚举和注解),提供访问保护和命名空间管理。
Java 中的一些现有包是 -
-
java.lang − 捆绑基础类
-
java.io − 输入、输出函数的类都捆绑在这个包中
程序员可以定义自己的包来捆绑类/接口组等。将您实现的相关类分组是一个很好的做法,以便程序员可以轻松确定类、接口、枚举和注释是相关的。主页>
由于包创建了一个新的命名空间,因此不会与其他包中的名称发生任何名称冲突。使用包,更容易提供访问控制,也更容易定位相关类。
创建一个包
创建包时,您应该为包选择一个名称并包含一个包 在每个源文件的顶部加上该名称,其中包含要包含在包中的类、接口、枚举和注释类型。
package 语句应该是源文件的第一行。每个源文件中只能有一个包语句,并且适用于文件中的所有类型。
如果没有使用 package 语句,那么类、接口、枚举和注解类型将被放置在当前的默认包中。
要使用 package 语句编译 Java 程序,您必须使用 -d 选项,如下所示。
javac -d Destination_folder file_name.java
然后在指定的目的地创建一个具有给定包名的文件夹,编译后的类文件将放置在该文件夹中。
示例
让我们看一个创建名为 animals 的包的示例 .使用小写字母的包名称是一个很好的做法,以避免与类和接口的名称发生任何冲突。
以下包示例包含名为 animals 的接口 -
/* File name : Animal.java */ package animals; interface Animal { public void eat(); public void travel(); }
现在,让我们在同一个包 animals 中实现上述接口 -
package animals; /* File name : 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 的包/文件夹 将在当前目录中创建,这些类文件将放置在其中,如下所示。
可以执行包内的class文件,得到如下结果。
Mammal eats Mammal travels
导入关键字
如果一个类要使用同一个包中的另一个类,则不需要使用包名。同一包中的类无需任何特殊语法即可相互查找。
示例
这里,一个名为 Boss 的类被添加到已经包含 Employee 的工资包中。然后 Boss 可以在不使用工资单前缀的情况下引用 Employee 类,如下面的 Boss 类所示。
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 语句必须出现在 package 语句之后和 class 声明之前。
包的目录结构
将类放入包中时会出现两个主要结果 -
-
包名成为类名的一部分,正如我们在上一节中讨论的那样。
-
包名必须与对应字节码所在的目录结构相匹配。
这是用 Java 管理文件的简单方法 -
将类、接口、枚举或注释类型的源代码放在一个文本文件中,该文件的名称是该类型的简单名称,其扩展名为 .java .
例如 -
// File Name : Car.java package vehicle; public class Car { // Class implementation. }
现在,将源文件放在一个目录中,该目录的名称反映了该类所属包的名称 -
....\vehicle\Car.java
现在,合格的类名和路径名如下 -
- 类名 → 车辆.Car
- 路径名 → 车辆\Car.java(在 Windows 中)
一般情况下,公司使用其反向互联网域名作为其包名称。
示例 − 一家公司的互联网域名是apple.com,那么它所有的包名都以com.apple 开头。包名的每个组件对应一个子目录。
示例 − 该公司有一个 com.apple.computers 包,其中包含一个 Dell.java 源文件,它会包含在一系列子目录中,如下所示 −
....\com\apple\computers\Dell.java
在编译时,编译器为其中定义的每个类、接口和枚举创建不同的输出文件。输出文件的基本名称是类型的名称,其扩展名是 .class .
例如 -
// File Name: 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
通过这样做,可以在不泄露您的源代码的情况下将访问类目录的权限授予其他程序员。您还需要以这种方式管理源文件和类文件,以便编译器和 Java 虚拟机 (JVM) 可以找到您的程序使用的所有类型。
类目录的完整路径
假设
一个类路径可能包括多个路径。多个路径应该用分号 (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 变量 -
- 在 Windows 中 → 设置 CLASSPATH =C:\users\jack\java\classes
- 在 UNIX 中 → % CLASSPATH =/home/jack/java/classes;导出类路径
java