Java基础知识13-枚举

Java基础知识13-枚举_第1张图片

枚举

从 JDK 5 开始, 枚举被添加到了 Java 语言中, 和其它语言中的描述相似, 但是这种相似只是表面上的.

枚举的基础知识

创建枚举需要使用 enum 关键字, 例如:

enum Apple {
  Jonathan, GoldenDel, RedDel, Winesap, Cortland
}

标识符 Jonathan, GoldenDel 等被称为枚举常量. 每个枚举常量被隐式声明为 Apple 的公有,静态 final 成员.

此外, 枚举常量的类型是声明它们的枚举类型, 对于这个例子为 Apple.

定义了枚举之后, 可以创建枚举类型的变量. 但是, 尽管枚举定义了类类型, 却不能使用 new 实例化枚举. 反而, 枚举变量的声明和使用方式在许多方面与基本类型相同.

下面这行代码将 ap 声明为 Apple 枚举类型的变量:

Apple ap;

因为 ap 是 Apple 类型, 所以只能被赋值为(或包含)在 Apple 枚举中定义的那些值.

例如, 下面这行代码将 ap 赋值为 RedDel;

ap = Apple.RedDel;

可以使用关系运算符 == 比较两个枚举常量的相等性. 例如, 下面这条语句比较 ap 的值和 GoldenDel 常量:

if (ap == Apple. GoldenDel) // ...

枚举值也可以用于控制 switch 语句. 当然, 所有的 case 语句使用的常量的枚举类型, 都必须与 switch 表达式使用的枚举类型相同.

switch (ap) {
  case Jonathan:
    // ...
  case Winesap:
    // ...

注意在 case 语句中, 枚举常量的名称没有使用枚举类型的名称进行限定. 也就是说, 使用的是 Winesap 而不是 Apple.Winesap.
这是因为 switch 表达式中的枚举类型已经隐式指定了 case 常量的枚举类型, 所以在 case 语句中不需要使用枚举类型的名称对常量进行限定. 实际上, 如果试图这么做的话, 会造成编译时错误.

values() 和 valuesOf() 方法

所有枚举都自动包含两个预定义方法: values() 和 valuesOf() 方法. 它们的一般形式如下所示:

public static enum-type [ ] values()
public static enum-type valueOf(String str)

values() 方法返回一个包含枚举常量列表的数据, valueOf()方法返回与传递到参数 str 的字符串相对应的常量.

Java 枚举是类类型

Java 枚举是类类型. 虽然不能使用 new 实例化枚举, 但是枚举却又许多和类相同的功能.

枚举定义了类, 这为 Java 枚举提供了超乎寻常的功能. 例如, 可以为枚举提供构造函数, 添加实例变量和方法, 甚至可以实现接口.

需要理解的重要一点是: 每个枚举常量都是枚举类型的对象. 因此, 如果为枚举定义了构造函数, 那么当创建每个枚举常量时都会调用该构造函数.

分析下面 Apple 枚举:

enum Apple{
  Jonathan(10), GoldenDel(9), RedDel(20), Winesap(15), Cortland(8);
  
  private int price;
  
  Apple(int p) { price = p;}

  int getPrice() { return price; }
}

这个版本的 Apple 枚举添加了三个内容: 第一个内容是实例变量 price, 用于保存每种苹果的价格; 第二个内容是 Apple 构造函数, 它以苹果的价格作为参数; 第三个内容是 getPrice() 方法, 用于返回 Price 变量的值.

当在 main() 方法中声明变量 ap 时, 对于每个特定的常量调用 Apple 构造函数一次.

注意指定构造函数参数的方式, 通过将它们放置到每个常量后面的圆括号中来加以指定, 如下所示:

Jonathan(10), GoldenDel(9), RedDel(20), Winesap(15), Cortland(8);

这些数值被传递给 Apple() 的参数 p, 然后将这些值赋值给 price 变量. 再强调一次, 为每个常量调用构造函数一次.

因为每个枚举常量都有自己的 price 变量副本, 所以可以调用 getPrice() 方法来获取指定类型苹果的价格.

Apple.Winesap.getPrice();

枚举继承自 Enum 类

尽管声明枚举时不能继承超类, 但是所有枚举都自动继承超类 java.lang.Enum , 这个类定义了所有枚举都可以使用的一些方法.

可以获取用于指示枚举常量在常量列表中位置的值, 这种称为枚举常量的序数值. 通过 ordinal() 方法可以检索序数值, 该方法的声明如下所示:

final int ordinal();

该方法返回调用常量的序数值, 序数值从0开始. 因此 Apple 枚举中, Jonathan 的序数值为 0, GoldenDel 的序数值为 1.

可以使用 compareTo() 方法比较相同类型的两个枚举常量的序数值, 该方法的一半形式如下:

final int compareTo( enum-type e );

其中, enum-tpye 是枚举的类型, e 是和调用常量进行比较的常量. 请记住, 调用常量和 e 必须是相同的枚举.

如果调用常量的序数值小于 e 的序数值, 那么 compareTo() 方法返回负值; 如果两个序数值相同, 返回0; 如果调用常量的序数值大于 e 序数值, 就返回正值.

你可能感兴趣的:(Java基础知识13-枚举)