Java包(package)

Java包简介

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。它是类的一种文件组织和管理方式、是一组功能相似或相关的类或接口的集合。

Java package提供了访问权限和命名的管理机制,它是Java中很基础却又非常重要的一个概念。

 

包的作用

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

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

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

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

包语句的语法格式为:

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

例如下面的Test.java文件的内容,那么它的路径应该是 com/csdn/zwj/Test.java 这样保存的。

package com.csdn.zwj;
public class Test{
   //...
}

package(包) 的作用是把不同的 java 程序分类保存,更方便的被其他 java 程序调用。一个包(package)可以定义为一组相互联系的类型(类、接口、枚举和注释),为这些类型提供访问保护和命名空间管理的功能。录入以下一些Java中的包:、

        java.lang-打包基础的类

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

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

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

 

创建包

创建包的时候,你需要为这个包取一个合适的名字。之后,如果其他的一个源文件包含了这个包提供的类、接口、枚举或者注释类型的时候,都必须将这个包的声明放在这个源文件的开头。

包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。

如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包(unnamed package)中。

下面我们看一个例子:

/* 文件名:Test.java */
package com.csdn.zwj; // 通常使用小写的字母来命名避免与类、接口名字的冲突。
 
interface TestInterFace{ // 接口
   public void run();
   public void eat();
}

注意

1)为了尽量使包名保持唯一性,包名通常采用小写、按倒写互联网址的形式进行定义。如:com.zwj.www表示包文件放置的文件路径为com/zwj/www。

2) 在进行命名包时,应该避免使用与系统发生冲突的名字,如java.lang、java.util等。

 

导入包

为了能够使用某一个包的成员,我们需要在 Java 程序中明确导入该包。使用 "import" 语句可完成此功能。在 java 源文件中可以包含任意数量的 import 声明,并且 import 语句应位于 package 语句之后,所有类的定义之前,可以没有,也可以有多条,其语法格式为:

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

如果在一个包中,一个类想要使用本包中的另一个类,那么该包名可以省略。如果不在一个包内,必须使用下面几种方法之一来引用其他包中的类。

1)使用类全名描述,例如:

java.lang.String

2)用 import 关键字引入,使用通配符 "*"

import java.lang.*;

3)使用 import 关键字引入 String类

import java.lang.String;

 

Java包的静态导入

import static静态导入是JDK1.5中的新特性。是对于import语句的加强。

要使用静态成员(方法和变量)我们必须给出提供这个静态成员的类,使用静态导入可以使被导入类的静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。

使用静态导入的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…),在使用时直接print(…)就可以了。 但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便。

静态导入的语法:

注意导入的是成员变量和方法名。

import static 包名.类名.静态成员变量; 
import static 包名.类名.静态成员函数; 
import static 包名.类名.*;

下面看个使用静态导入的简单例子:

import static java.lang.System.out; 
import static java.lang.Integer.*; 

public class Test {
    public static void main(String[] args) {
        out.println(MAX_VALUE);   // int类型最大值 2147483647
        out.println(toHexString(42));  // 转换为16进制 2a

    }
}

虽然该特性通常称为“静态导入”,但语法必须是import static,后面跟想导入的static成员的完全限定名称,或者通配符。在本例中,我们在System类的out对象上进行静态导入,也使用了通配符在java.lang.Integer类中的所有静态成员上进行了静态导入。

 

使用静态导入的原则:

1)必须是import static, 不能是static import。

2)提防含糊不清的命名static成员。例如,如果对Integer类和Long类执行了静态导入,引用MAX_VALUE将导致一个编译器错误,因为Integer和Long都有一个MAX_VALUE常量,并且Java不会知道你在引用哪个MAX_VALUE。

3)可以在static对象引用、常量(记住,它们是static 或final)和static方法上进行静态导入。

 

使用静态导入的优点:

减少字符输入量,提高代码的可阅读性,以便更好地理解程序。 

使用静态导入的缺点:

滥用静态导入会使程序更难阅读,更难维护。静态导入后,代码中就不用再写类名了,但是我们知道类是“一类事物的描述”,缺少了类名的修饰,静态属性和静态方法的表象意义可以被无限放大,这会让阅读者很难弄清楚其属性或方法代表何意,甚至是哪一个类的属性(方法)都要思考一番,特别是在一个类中有多个静态导入语句时,若还使用了*通配符,把一个类的所有静态元素都导入进来了,那简直就是恶梦。

 

eclipse中支持静态导入的设置

eclipse中的自动导入(即ctrl+shift+o )是非静态导入,如果是支持静态导入需要去开启静态导入操作:

点击Window -> Preferences -> Java -> Editor -> Content Assist

点击“static imports” 进入以下界面,然后点击“New Member...”进行设置静态类型或静态方法。

 

package的目录结构

类放在包中会有两种主要的结果:

1)包名成为类名的一部分,正如我们前面讨论的一样。

2)包名必须与相应的字节码所在的目录结构相吻合。

下面是管理你自己 java 中文件的一种简单方式:

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

// 文件名 :  Car.java
package vehicle; 
public class Car {
    // 类实现  
}

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

....\vehicle\Car.java

现在,正确的类名和路径将会是如下样子:

          类名 -> vehicle.Car

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

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

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

...\com\zwj\test\Zwj.java

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

// 文件名: Test.java
package com.zwj.test;
public class Test {     
}
class Test2 {      
}

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

$javac -d . Test.java

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

.\com\zwj\test\Test.class
.\com\zwj\test\Test2.class

我们可以像下面这样来导入所有 \com\zwj\test\ 中定义的类、接口等:

import com.zwj.test.*;

编译之后的 .class 文件应该和 .java 源文件一样,它们放置的目录应该跟包的名字对应起来。但是,并不要求 .class 文件的路径跟相应的 .java 的路径一样。我们可以分开来安排源码和类的目录。

<path-one>\sources\com\zwj\test\Test.java
<path-two>\classes\com\zwj\test\Test.class

这样,我们可以将类目录分享给其他的编程人员,而不用透露自己的源码。用这种方法管理源码和类文件可以让编译器和java 虚拟机(JVM)可以找到我们程序中使用的所有类型。

类目录的绝对路径叫做 class path。设置在系统变量 CLASSPATH 中。编译器和 java 虚拟机通过将 package 名字加到 class path 后来构造 .class 文件的路径。

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

一个 class path 可能会包含好几个路径,多路径应该用分隔符分开。默认情况下,编译器和 JVM 查找当前目录。JAR 文件按包含 Java 平台相关的类,所以他们的目录默认放在了 class path 中。

 

 

 

猜你喜欢

转载自blog.csdn.net/lxxiang1/article/details/82049655
今日推荐