使用包成员
组成包的类型称为包成员。
要从其包外部使用公共包成员,你必须执行以下操作之一:
- 通过其完全限定名称引用该成员
- 导入包成员
- 导入成员的整个包
每种情况都适用于不同的情况,如以下各节所述。
通过其完全限定名称引用包成员
到目前为止,本教程中的大多数示例都通过简单名称引用类型,例如Rectangle
和StackOfInts
,如果你编写的代码与该成员位于同一个包中,或者已导入该成员,则可以使用包成员的简单名称。
但是,如果你尝试使用其他包中的成员并且尚未导入该包,则必须使用该成员的完全限定名称,该名称包括包名称,这是上一个示例中graphics
包中声明的Rectangle
类的完全限定名称。
graphics.Rectangle
你可以使用此限定名称来创建graphics.Rectangle
的实例:
graphics.Rectangle myRect = new graphics.Rectangle();
限定名称不经常使用,重复使用名称时,重复键入名称会变得乏味,代码变得难以阅读,或者,你可以导入成员或其包,然后使用其简单名称。
导入包成员
要将特定成员导入当前文件,请在任何类型定义之前在文件开头放置import
语句,但在package
语句之后(如果有),以下是从上一节中创建的graphics
包导入Rectangle
类的方法。
import graphics.Rectangle;
现在你可以通过简单名称引用Rectangle
类。
如果你只使用graphics
包中的一些成员,这种方法很有效,但是如果从包中使用多种类型,则应导入整个包。
导入整个包
要导入特定包中包含的所有类型,请使用带有星号(*
)通配符的import
语句。
import graphics.*;
现在,你可以通过简单名称引用graphics
包中的任何类或接口。
Circle myCircle = new Circle();
Rectangle myRectangle = new Rectangle();
import
语句中的星号只能用于指定包中的所有类,如此处所示,它不能用于匹配包中类的子集,例如,以下内容与graphics
包中以A
开头的所有类都不匹配。
// does not work
import graphics.A*;
相反,它会生成编译器错误,使用import
语句,通常只导入单个包成员或整个包。
另一种不太常见的导入形式允许你导入封闭类的公共嵌套类,例如,如果graphics.Rectangle
类包含有用的嵌套类(如Rectangle.DoubleWide
和Rectangle.Square
),则可以使用以下两个语句导入Rectangle
及其嵌套类。
import graphics.Rectangle;
import graphics.Rectangle.*;
请注意,第二个import
语句不会导入Rectangle
。
另一种不常见的导入形式是静态导入语句,将在本节末尾讨论。
为方便起见,Java编译器会自动为每个源文件导入两个完整的包:java.lang
包和当前包(当前文件的包)。
包的表观层次结构
首先,包似乎是分层的,但它们不是,例如,Java API包括java.awt
包,java.awt.color
包,java.awt.font
包以及许多以java.awt
开头的包。但是,java.awt
包中包含java.awt.color
包、java.awt.font
包和其他java.awt.xxxx
包。前缀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.*;
名称歧义
如果一个包中的成员与另一个包中的成员共享其名称并且两个包都已导入,则必须通过其限定名称引用每个成员,例如,graphics
包定义了一个名为Rectangle
的类,java.awt
包还包含一个Rectangle
类,如果已导入graphics
和java.awt
,则以下内容不明确。
Rectangle rect;
在这种情况下,你必须使用成员的完全限定名称来准确指出你想要的Rectangle
类,例如:
graphics.Rectangle rect;
静态导入语句
在某些情况下,你需要频繁访问static final
字段(常量)和来自一个或两个类的静态方法,反复对这些类的名称进行前缀可能会导致代码混乱,static 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);
显然,你可以编写自己的类,其中包含你经常使用的常量和静态方法,然后使用static import
语句,例如:
import static mypackage.MyConstants.*;
非常谨慎地使用static import
,过度使用静态导入会导致代码难以阅读和维护,因为代码的读者不知道哪个类定义了特定的静态对象,正确地使用,static import
通过删除类名重复使代码更具可读性。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。