Java Enum 分析

 

枚举的用途

枚举是一中特殊的数据类型, 枚举中的变量是我们预先设定的一组值, 并且该组值是固定,无法增删改的.

  • 我们可以用来记录一些特殊的值, 比如星期几, 东西南北方向, 性别等,
  • 用Enum可以实现单例模式, 用Enum实现单例模式是一种很优雅的方式, 它的优点:
    • 保证是线程安全的
    • 序列化不会破坏用枚举实现的单例

      枚举的示例

      示例1:
package com.myEnum;

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;
}
示例2:
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));
    }
}

第二个示例的输出结果:

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

从示例中我们可以得知: 枚举有自己的默认构造方法, 可以根据自己的需求写出一个枚举类型.

其实仔细一看, 和我们写一个类是一样的, (你可以看下枚举类型的反编译代码, 其实就是一个final类继承了Enum抽象类),只不过, 枚举需要我们在其中设定具体的常量去”填充”这个枚举, 这样枚举才有意义.

经过java -p 反编译过的示例2:

public final class com.myEnum.Planet extends java.lang.Enum<com.myEnum.Planet> {
  public static final com.myEnum.Planet MERCURY;
  public static final com.myEnum.Planet VENUS;
  public static final com.myEnum.Planet EARTH;
  public static final com.myEnum.Planet MARS;
  public static final com.myEnum.Planet JUPITER;
  public static final com.myEnum.Planet SATURN;
  public static final com.myEnum.Planet URANUS;
  public static final com.myEnum.Planet NEPTUNE;
  private final double mass;
  private final double radius;
  public static final double G;
  private static final com.myEnum.Planet[] $VALUES;
  public static com.myEnum.Planet[] values();
  public static com.myEnum.Planet valueOf(java.lang.String);
  private com.myEnum.Planet(double, double);
  private double mass();
  private double radius();
  double surfaceGravity();
  double surfaceWeight(double);
  public static void main(java.lang.String[]);
  static {};
}