使用包成员
原文: https://docs.oracle.com/javase/tutorial/java/package/usepkgs.html
组成包的类型称为包成员。
要从包外部使用public
包成员,您必须执行以下操作之一:
- 请通过其完全限定名称引用该成员
- 导入包成员
- 导入成员的整个包
每种情况都适用于不同的情况,如以下各节所述。
以合格名称提及包裹成员
到目前为止,本教程中的大多数示例都通过简单名称引用类型,例如Rectangle
和StackOfInts
。如果您编写的代码与该成员位于同一个包中,或者已导入该成员,则可以使用包成员的简单名称。
但是,如果您尝试使用其他程序包中的成员并且尚未导入该程序包,则必须使用该成员的完全限定名称,该名称包括程序包名称。这是上一个示例中graphics
包中声明的Rectangle
类的完全限定名称。
graphics.Rectangle
您可以使用此限定名称来创建graphics.Rectangle
的实例:
graphics.Rectangle myRect = new graphics.Rectangle();
合格的名称可以不经常使用。但是,当重复使用名称时,重复键入名称会变得乏味,并且代码变得难以阅读。作为替代方案,您可以导入成员或其包,然后使用其简单名称。
导入包成员
要将特定成员导入当前文件,请在任何类型定义之前在文件开头放置import
语句,但在package
语句之后(如果有)。以下是从上一节中创建的graphics
包导入Rectangle
类的方法。
import graphics.Rectangle;
现在您可以通过简单名称来引用Rectangle
类。
Rectangle myRectangle = new Rectangle();
如果您只使用graphics
包中的几个成员,这种方法很有效。但是如果从包中使用多种类型,则应导入整个包。
导入整个包
要导入特定包中包含的所有类型,请使用带有星号(*)
通配符的import
语句。
import graphics.*;
现在,您可以通过简单名称引用graphics
包中的任何类或接口。
Circle myCircle = new Circle();
Rectangle myRectangle = new Rectangle();
import
语句中的星号只能用于指定包中的所有类,如此处所示。它不能用于匹配包中类的子集。例如,以下内容与graphics
包中以A
开头的所有类都不匹配。
// does not work
import graphics.A*;
相反,它会生成编译器错误。使用import
语句,通常只导入单个包成员或整个包。
Note: Another, less common form of import
allows you to import the public nested classes of an enclosing class. For example, if the graphics.Rectangle
class contained useful nested classes, such as Rectangle.DoubleWide
and Rectangle.Square
, you could import Rectangle
and its nested classes by using the following two statements.
import graphics.Rectangle;
import graphics.Rectangle.*;
Be aware that the second import statement will not import Rectangle
.
Another less common form of import
, the static import statement, will be discussed at the end of this section.
为方便起见,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.*;
名称含糊不清
如果一个包中的成员与另一个包中的成员共享其名称并且两个包都已导入,则必须通过其限定名称引用每个成员。例如,graphics
包定义了一个名为Rectangle
的类。 java.awt
包还包含Rectangle
类。如果已导入graphics
和java.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);
您可以使用 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: Use static import very sparingly. Overusing static import can result in code that is difficult to read and maintain, because readers of the code won’t know which class defines a particular static object. Used properly, static import makes code more readable by removing class name repetition.