本资料来自于runoob,略有修改。

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

Java 使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。

 

一、包的作用

1、把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。

2、如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

3、包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

 

二、打包

2.1 包的语法

package pkg1[.pkg2[.pkg3…]];

例如,一个Something.java 文件它的内容

package net.java.util;

public class Something{

...

}

那么它的路径应该是 net/java/util/Something.java 这样保存的。

package(包) 的作用是把不同的 java 程序分类保存,更方便的被其他 java 程序调用。

 

一个包(package)可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能。

以下是一些 Java 中的包:

java.lang-打包基础的类

java.io-包含输入输出功能的函数

开发者可以自己把一组类和接口等打包,并定义自己的包。而且在实际开发中这样做是值得提倡的,当你自己完成类的实现之后,将相关的类分组,可以让其他的编程者更容易地确定哪些类、接口、枚举和注释等是相关的。

由于包创建了新的命名空间(namespace),所以不会跟其他包中的任何名字产生命名冲突。使用包这种机制,更容易实现访问控制,并且让定位相关类更加简单。

2.2 创建包

通常使用小写的字母来命名避免与类、接口名字的冲突。

例子:创建了一个叫做animals的包。

animals 包中加入一个接口(interface):

/* 文件名: Animal.java */

package animals;

interface Animal {

public void eat();

public void travel();

}

在同一个包中加入该接口的实现

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

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();

}

}

 

编译

这两个文件,把他们放在一个叫做animals的子目录中。 

$ mkdir animals

$ cp Animal.class MammalInt.class animals

$ java animals/MammalInt

Mammal eats

Mammal travel

 

三、import的两种方式

使用某一个包的成员,我们需要"import" 语句明确导入该包。

import 声明必须在包声明之后,类声明之前。

语法

import package1[.package2…].(classname|*);

例子

payroll 包已经包含了 Employee 类,接下来向 payroll 包中添加一个 Boss 类。Boss 类引用 Employee 类的时候可以不用使用 payroll 前缀。

如果 Boss 类不在 payroll 包中,Boss 类可如下方式引用其它包中的类。

类全名描述

payroll.Employee

import 使用通配符 * 引入

import payroll.*;

import 直接引入

import payroll.Employee;

四、包的目录结构

类放在包中会有两种主要的结果:包名成为类名的一部分;包名必须与相应的字节码所在的目录结构相吻合。

4.1 简单方式

将类、接口等类型的源码放在一个文本中,这个文件的名字就是这个类型的名字,并以.java作为扩展名。

// 文件名 : Car.java

package vehicle;

public class Car {

// 类实现

}

接下来,把源文件放在一个目录中,这个目录要对应类所在包的名字。

....\vehicle\Car.java

类名和路径将会是

类名 : vehicle.Car

路径名:vehicle\Car.java (在 windows 系统中)

4.2 常用方式

通常,一个公司使用它互联网域名的颠倒形式来作为它的包名.例如:互联网域名是 runoob.com,所有的包名都以 com.runoob 开头。包名中的每一个部分对应一个子目录。

例如:有一个 com.runoob.test 的包,这个包包含一个叫做 Runoob.java 的源文件,那么相应的,应该有如下面的一连串子目录:

....\com\runoob\test\Runoob.java

 

4.3 编译包

编译的时候,编译器为包中定义的每个类、接口等类型各创建一个不同的输出文件,输出文件的名字就是这个类型的名字,并加上 .class 作为扩展后缀。 例如:

// 文件名: Runoob.java

package com.runoob.test;

public class Runoob {

}

class Google {

}

现在,我们用-d选项来编译这个文件,如下:

//一个包的文件都在时编译$javac -d . Runoob.java//只有一个文件时编译javac A.java

运行:编译之后会自己生成文件夹,不要进入这个文件夹,直接运行 java -cp /home/test test.Run,其中源文件在 test 文件夹中,包名为 test,启动文件为 Run.java。

 

这样会像下面这样放置编译了的文件:

.\com\runoob\test\Runoob.class

.\com\runoob\test\Google.class

导入所有 \com\runoob\test\ 中定义的类、接口等的示例

import com.runoob.test.*;

 

编译之后的 .class 文件应该和 .java 源文件一样,它们放置的目录应该跟包的名字对应起来。

但是,并不要求 .class 文件的路径跟相应的 .java 的路径一样。你可以分开来安排源码和类的目录。

\sources\com\runoob\test\Runoob.java

\classes\com\runoob\test\Google.class

这样,你可以将你的类目录分享给其他的编程人员,而不用透露自己的源码。

用这种方法管理源码和类文件可以让编译器和java 虚拟机(JVM)可以找到你程序中使用的所有类型。

 

4.4 class path

类目录的绝对路径叫做 class path。设置在系统变量 CLASSPATH 中。

编译器和 java 虚拟机通过将 package 名字加到 class path 后来构造 .class 文件的路径。

\classes 是 class path,package 名字是 com.runoob.test, 而编译器和 JVM 会在 \classes\com\runoob\test 中找 .class 文件。

一个 class path 可能会包含好几个路径,多路径应该用分隔符分开。

默认情况下,编译器和 JVM 查找当前目录。JAR 文件按包含 Java 平台相关的类,所以他们的目录默认放在了 class path 中。

 

五、idea下打包与使用

见本人的博客  idea下java项目的打包与使用

 

查看原文