文档

Java™ 教程
隐藏目录
使用包成员
目录: 学习Java语言
课程:
章节: 创建和使用包

使用包成员

包中包含的类型称为包成员

要从包外部使用一个public包成员,您必须执行以下操作之一:

每种情况适用于不同的情况,如下面的各节所述。

通过其限定名称引用包成员

到目前为止,在本教程中的大多数示例中,类型都是通过它们的简单名称引用的,例如RectangleStackOfInts。如果您正在编写的代码与该成员位于同一个包中,或者已经导入了该成员,则可以使用包成员的简单名称。

然而,如果您正在尝试使用来自不同包的成员,并且该包尚未被导入,则必须使用成员的完全限定名称,其中包括包名称。下面是先前示例中在graphics包中声明的Rectangle类的完全限定名称。

graphics.Rectangle

您可以使用此限定名称创建一个graphics.Rectangle的实例:

graphics.Rectangle myRect = new graphics.Rectangle();

限定名称对于偶尔使用是可以的。但是,当一个名称被反复使用时,反复输入名称变得乏味,并且代码变得难以阅读。作为替代方案,您可以导入该成员或其包,然后使用其简单名称。

导入包成员

要将特定成员导入到当前文件中,请在文件开头的任何类型定义之前(如果有的话,在package语句之后)放置一个import语句。下面是如何导入先前部分中创建的graphics包中的Rectangle类。

import graphics.Rectangle;

现在您可以使用Rectangle类的简单名称。

Rectangle myRectangle = new Rectangle();

如果您只从graphics包中使用少量成员,则此方法很有效。但是,如果您从包中使用许多类型,则应导入整个包。

导入整个包

要导入包中包含的所有类型,请使用import语句与星号(*)通配符字符。

import graphics.*;

现在您可以通过其简单名称引用graphics包中的任何类或接口。

Circle myCircle = new Circle();
Rectangle myRectangle = new Rectangle();

import语句中的星号只能用于指定包中的所有类,如上所示。它不能用于匹配包中的类的子集。例如,以下内容不匹配以A开头的graphics包中的所有类。

// 无法工作
import graphics.A*;

相反,这将导致编译错误。使用import语句时,通常只导入一个单独的包成员或整个包。


注意: 另一种较少使用的import形式允许您导入封闭类的公共嵌套类。例如,如果graphics.Rectangle类包含有用的嵌套类,如Rectangle.DoubleWideRectangle.Square,则可以使用以下两个语句导入Rectangle及其嵌套类。
import graphics.Rectangle;
import graphics.Rectangle.*;
请注意,第二个导入语句不会导入Rectangle

另一种较少使用的import形式,即静态导入语句,将在本节末尾讨论。

为了方便起见,Java编译器会自动为每个源文件导入两个完整的包:(1) java.lang包和(2) 当前包(当前文件所在的包)。

包的显式层级

起初,包似乎是有层次结构的,但实际上并非如此。例如,Java API包括一个java.awt包,一个java.awt.color包,一个java.awt.font包和许多其他以java.awt开头的包。然而,java.awt.color包,java.awt.font包和其他java.awt.xxxx包并未包含在java.awt包中。前缀java.awt(Java抽象窗口工具包)用于一些相关的包,以显示它们之间的关系,但并不表示包含关系。

导入java.awt.*会导入java.awt包中的所有类型,但不会导入java.awt.colorjava.awt.font或任何其他java.awt.xxxx包。如果您计划同时使用java.awt.color中的类和其他java.awt中的类,您必须导入这两个包及其所有文件:

import java.awt.*;
import java.awt.color.*;

名称冲突

如果一个包中的成员与另一个包中的成员共享相同的名称,并且两个包都已导入,您必须使用每个成员的限定名称来指定要使用的确切Rectangle类。例如,graphics包定义了一个名为Rectangle的类。而java.awt包也包含一个Rectangle类。如果graphicsjava.awt都已导入,下面的代码是有歧义的。

Rectangle rect;

在这种情况下,您必须使用成员的完全限定名称来明确指定要使用的Rectangle类。例如:

graphics.Rectangle rect;

静态导入语句

在某些情况下,您需要频繁访问一个或两个类的静态常量和静态方法。每次都在这些类的名称前面加上前缀可能会导致代码混乱。静态导入语句提供了一种导入要使用的常量和静态方法的方式,这样您就不需要在它们的类名称前面加上前缀。

java.lang.Math类定义了PI常量和许多静态方法,包括计算正弦、余弦、正切、平方根、最大值、最小值、指数等方法。例如,

public static final double PI 
    = 3.141592653589793;
public static double cos(double a)
{
    ...
}

通常情况下,要从另一个类中使用这些对象,您需要在类名称前加上前缀,如下所示。

double r = Math.cos(Math.PI * theta);

您可以使用静态导入语句导入java.lang.Math的静态成员,这样您就不需要在类名称Math前加上前缀。可以分别导入Math的静态成员:

import static java.lang.Math.PI;

或者导入一组静态成员:

import static java.lang.Math.*;

一旦导入了这些静态成员,就可以在不加限定符的情况下使用它们。例如,上面的代码片段将变为:

double r = cos(PI * theta);

显然,您可以编写自己的类,其中包含您经常使用的常量和静态方法,然后使用静态导入语句。例如,

import static mypackage.MyConstants.*;

注意:请非常谨慎地使用静态导入。过度使用静态导入可能导致代码难以阅读和维护,因为代码的读者将无法知道哪个类定义了特定的静态对象。正确使用静态导入可以通过消除类名称的重复来使代码更可读。

上一页: 命名包
下一页: 管理源码和类文件