使用包成员
组成包装的类型称为包装成员。
要从其软件包外部使用public
软件包成员,必须执行以下操作之一:
-
用完全限定的名称称呼该会员
-
导入包成员
-
导入会员的整个package
每种方法都适用于不同的情况,如以下各节所述。
用合格名称提及package会员
到目前为止,本教程中的大多数示例都通过简单名称来引用类型,例如Rectangle
和StackOfInts
。如果您要编写的代码与该成员位于同一软件包中,或者已导入该成员,则可以使用该成员的简单名称。
但是,如果您try使用来自其他软件包的成员,而该软件包尚未导入,则必须使用成员的全限定名,其中包括软件包名称。这是上一个示例中graphics
包中声明的Rectangle
类的完全限定名称。
graphics.Rectangle
您可以使用此限定名来创建graphics.Rectangle
的实例:
graphics.Rectangle myRect = new graphics.Rectangle();
合格的名称可以不经常使用。但是,当重复使用名称时,重复 Importing 名称将变得乏味,并且代码变得难以阅读。或者,您可以导入成员或其包,然后使用其简单名称。
导入软件包成员
要将特定成员导入当前文件,请将import
语句放在文件开头,然后放在任何类型定义之前,但在package
语句之后(如果有)。这是从上一部分中创建的graphics
包中导入Rectangle
类的方法。
import graphics.Rectangle;
现在,您可以通过其简单名称来引用Rectangle
类。
Rectangle myRectangle = new Rectangle();
如果仅使用graphics
包中的几个成员,则此方法效果很好。但是,如果您从包中使用许多类型,则应导入整个包。
导入整个程序包
要导入特定程序包中包含的所有类型,请使用带有星号(*)
通配符的import
语句。
import graphics.*;
现在,您可以通过graphics
包的简单名称来引用任何类或interface。
Circle myCircle = new Circle();
Rectangle myRectangle = new Rectangle();
import
语句中的星号只能用于指定包中的所有类,如下所示。它不能用于匹配包中类的子集。例如,以下代码与A
开头的graphics
包中的所有类都不匹配。
// does not work
import graphics.A*;
而是,它生成一个编译器错误。使用import
语句,通常只导入一个包成员或整个包。
Note:
另一种不太常见的import
形式允许您导入封闭类的公共嵌套类。例如,如果graphics.Rectangle
类包含有用的嵌套类,例如Rectangle.DoubleWide
和Rectangle.Square
,则可以使用以下两个语句导入Rectangle
及其嵌套类。
import graphics.Rectangle;
import graphics.Rectangle.*;
请注意,第二个 import 语句将不会导入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.color
,java.awt.font
或任何其他java.awt.xxxx
包。如果计划使用java.awt.color
以及java.awt
中的类和其他类型,则必须导入两个包及其所有文件:
import java.awt.*;
import java.awt.color.*;
Name Ambiguities
如果一个包中的成员与另一个包中的成员共享其名称,并且两个包均已导入,则必须使用其限定名称来引用每个成员。例如,graphics
包定义了一个名为Rectangle
的类。 java.awt
程序包还包含Rectangle
类。如果graphics
和java.awt
都已导入,则以下内容不明确。
Rectangle rect;
在这种情况下,您必须使用成员的全限定名来准确指出您想要的Rectangle
类。例如,
graphics.Rectangle rect;
静态导入语句
在某些情况下,您需要经常访问一两个类的静态 final 字段(常量)和静态方法。一遍又一遍地加上这些类的名称可能会导致代码混乱。静态 import 语句为您提供了一种导入要使用的常量和静态方法的方法,因此您无需在其类名之前添加前缀。
java.lang.Math
类定义PI
常量和许多静态方法,包括用于计算正弦,余弦,正切,平方根,最大值,最小值,指数等的方法。例如,
public static final double PI
= 3.141592653589793;
public static double cos(double a)
{
...
}
通常,要使用另一个类中的这些对象,请在类名前添加前缀,如下所示。
double r = Math.cos(Math.PI * theta);
您可以使用 static import 语句来导入 java.lang.Math 的静态成员,这样就无需在类名Math
前面添加前缀。 Math
的静态成员可以单独导入:
import static java.lang.Math.PI;
或作为一个组:
import static java.lang.Math.*;
导入静态成员后,无需资格即可使用它们。例如,先前的代码片段将变为:
double r = cos(PI * theta);
显然,您可以编写自己的类,这些类包含经常使用的常量和静态方法,然后使用静态 import 语句。例如,
import static mypackage.MyConstants.*;
Note:
非常谨慎地使用静态导入。过度使用静态导入会导致代码难以阅读和维护,因为代码的 Reader 不会知道哪个类定义了特定的静态对象。通过正确使用静态导入,可以消除类名重复,从而使代码更具可读性。