使用包成员

原文: https://docs.oracle.com/javase/tutorial/java/package/usepkgs.html

组成包的类型称为包成员

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

  • 请通过其完全限定名称引用该成员
  • 导入包成员
  • 导入成员的整个包

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

以合格名称提及包裹成员

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

但是,如果您尝试使用其他程序包中的成员并且尚未导入该程序包,则必须使用该成员的完全限定名称,该名称包括程序包名称。这是上一个示例中graphics包中声明的Rectangle类的完全限定名称。

  1. graphics.Rectangle

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

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

合格的名称可以不经常使用。但是,当重复使用名称时,重复键入名称会变得乏味,并且代码变得难以阅读。作为替代方案,您可以导入成员或其包,然后使用其简单名称。

导入包成员

要将特定成员导入当前文件,请在任何类型定义之前在文件开头放置import语句,但在package语句之后(如果有)。以下是从上一节中创建的graphics包导入Rectangle类的方法。

  1. import graphics.Rectangle;

现在您可以通过简单名称来引用Rectangle类。

  1. Rectangle myRectangle = new Rectangle();

如果您只使用graphics包中的几个成员,这种方法很有效。但是如果从包中使用多种类型,则应导入整个包。

导入整个包

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

  1. import graphics.*;

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

  1. Circle myCircle = new Circle();
  2. Rectangle myRectangle = new Rectangle();

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

  1. // does not work
  2. 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.

  1. import graphics.Rectangle;
  2. 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.colorjava.awt.font或任何其他java.awt.xxxx包。如果您计划使用java.awt.color中的类和其他类型以及java.awt中的类,则必须导入包含所有文件的包:

  1. import java.awt.*;
  2. import java.awt.color.*;

名称含糊不清

如果一个包中的成员与另一个包中的成员共享其名称并且两个包都已导入,则必须通过其限定名称引用每个成员。例如,graphics包定义了一个名为Rectangle的类。 java.awt包还包含Rectangle类。如果已导入graphicsjava.awt,则以下内容不明确。

  1. Rectangle rect;

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

  1. graphics.Rectangle rect;

在某些情况下,您需要经常访问静态最终字段(常量)和来自一个或两个类的静态方法。反复对这些类的名称进行前缀可能会导致代码混乱。静态导入语句为您提供了一种导入要使用的常量和静态方法的方法,这样您就不需要为其类的名称添加前缀。

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

  1. public static final double PI
  2. = 3.141592653589793;
  3. public static double cos(double a)
  4. {
  5. ...
  6. }

通常,要从其他类使用这些对象,请在类名前加上,如下所示。

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

您可以使用 static import 语句导入 java.lang.Math 的静态成员,这样就不需要为类名Math添加前缀。 Math的静态成员可以单独导入:

  1. import static java.lang.Math.PI;

或作为一个群体:

  1. import static java.lang.Math.*;

导入后,可以无限制地使用静态成员。例如,之前的代码段将变为:

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

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

  1. 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.