70.md 5.9 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4
# 枚举类型

> 原文: [https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)

W
wizardforcel 已提交
5
*枚举类型*是一种特殊数据类型,它使变量成为一组预定义常量。变量必须等于为其预定义的值之一。常见示例包括罗盘方向(NORTH,SOUTH,EAST 和 WEST 的值)和星期几。
W
init  
wizardforcel 已提交
6 7 8 9 10

因为它们是常量,所以枚举类型字段的名称是大写字母。

在 Java 编程语言中,您可以使用`enum`关键字定义枚举类型。例如,您可以将星期几的枚举类型指定为:

W
wizardforcel 已提交
11
```java
W
init  
wizardforcel 已提交
12 13 14 15 16 17 18 19 20 21 22
public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY 
}

```

您需要在需要表示一组固定常量时使用枚举类型。这包括自然枚举类型,例如太阳系中的行星和数据集,您可以在编译时知道所有可能的值 - 例如,菜单上的选项,命令行标志等。

以下是一些代码,向您展示如何使用上面定义的`Day`枚举:

W
wizardforcel 已提交
23
```java
W
init  
wizardforcel 已提交
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
public class EnumTest {
    Day day;

    public EnumTest(Day day) {
        this.day = day;
    }

    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;

            case FRIDAY:
                System.out.println("Fridays are better.");
                break;

            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;

            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }

    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(Day.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(Day.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(Day.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(Day.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

```

输出是:

W
wizardforcel 已提交
69
```java
W
init  
wizardforcel 已提交
70 71 72 73 74 75 76 77
Mondays are bad.
Midweek days are so-so.
Fridays are better.
Weekends are best.
Weekends are best.

```

W
wizardforcel 已提交
78
Java 编程语言枚举类型比其他语言中的对应类型更强大。 `enum`声明定义*类*(称为*枚举类型*)。枚举类主体可以包括方法和其他字段。编译器在创建枚举时会自动添加一些特殊方法。例如,它们有一个静态`values`方法,该方法返回一个数组,该数组按照声明的顺序包含枚举的所有值。此方法通常与 for-each 构造结合使用,以迭代枚举类型的值。例如,下面`Planet`类示例中的代码迭代太阳系中的所有行星。
W
init  
wizardforcel 已提交
79

W
wizardforcel 已提交
80
```java
W
init  
wizardforcel 已提交
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
for (Planet p : Planet.values()) {
    System.out.printf("Your weight on %s is %f%n",
                      p, p.surfaceWeight(mass));
}

```

* * *

**Note:** _All_ enums implicitly extend `java.lang.Enum`. Because a class can only extend one parent (see [Declaring Classes](classdecl.html)), the Java language does not support multiple inheritance of state (see [Multiple Inheritance of State, Implementation, and Type](../IandI/multipleinheritance.html)), and therefore an enum cannot extend anything else.

* * *

在以下示例中,`Planet`是枚举类型,表示太阳系中的行星。它们具有恒定的质量和半径属性。

W
wizardforcel 已提交
96
每个枚举常量都声明为质量和半径参数的值。创建常量时,这些值将传递给构造器。 Java 要求在任何字段或方法之前首先定义常量。此外,当存在字段和方法时,枚举常量列表必须以分号结尾。
W
init  
wizardforcel 已提交
97 98 99 100 101 102 103

* * *

**Note:** The constructor for an enum type must be package-private or private access. It automatically creates the constants that are defined at the beginning of the enum body. You cannot invoke an enum constructor yourself.

* * *

W
wizardforcel 已提交
104
除了它的属性和构造器之外,`Planet`还有一些方法可以让你检索每个行星上一个物体的表面重力和重量。这是一个示例程序,它可以减轻地球上的重量(在任何单位)并计算并打印所有行星上的重量(在同一单位):
W
init  
wizardforcel 已提交
105

W
wizardforcel 已提交
106
```java
W
init  
wizardforcel 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    private double mass() { return mass; }
    private double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

```

如果从参数为 175 的命令行运行`Planet.class`,则会得到以下输出:

W
wizardforcel 已提交
152
```java
W
init  
wizardforcel 已提交
153 154 155 156 157 158 159 160 161 162 163
$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
Your weight on EARTH is 175.000000
Your weight on MARS is 66.279007
Your weight on JUPITER is 442.847567
Your weight on SATURN is 186.552719
Your weight on URANUS is 158.397260
Your weight on NEPTUNE is 199.207413

```