malinkang


人生最可悲的事情,莫过于胸怀大志,却又虚度光阴。


《Effective Java》读书笔记 第6章 枚举和注解

第30条:用enum代替int常量

在编程语言中还没有引入枚举类型之前,表示枚举类型的常量模式是声明一组具名的int常量,每个类型成员一个常量:

public static final int APPLE_FUJI = 0;
public static final int APPLE_PIPPIN = 1;
public static final int APPLE_GRANNY_SMITH = 2;

public static final int ORANGE_NAVEL = 0;
public static final int ORANGE_TEMPLE = 1;
public static final int ORANGE_BLOOD = 2;

这种方法称作int枚举模式。在这种模式中使用String常量,而不是int常量。这样的变体被称为String枚举模式

Java 1.5增加了枚举类型,可以避免intString枚举模式的缺点。

public enum Apple {FUJI, PIPPIN, GRANNY_SMITH}
public enum ORANGE {NAVEL, TEMPLE, BLOOD}

举个枚举类型的好例子:

public enum Planet {
    MERCURY(3.302e+23, 2.439e6),
    VENUS  (4.869e+24, 6.052e6),
    EARTH  (5.975e+24, 6.378e6),
    MARS   (6.419e+23, 3.393e6),
    JUPITER(1.899e+27, 7.149e7),
    SATURN (5.685e+26, 6.027e7),
    URANUS (8.683e+25, 2.556e7),
    NEPTUNE(1.024e+26, 2.477e7);

    private final double mass;           // In kilograms
    private final double radius;         // In meters
    private final double surfaceGravity; // In m / s^2

    // Universal gravitational constant in m^3 / kg s^2
    private static final double G = 6.67300E-11;

    // Constructor
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
        surfaceGravity = G * mass / (radius * radius);
    }

    public double mass()           { return mass; }
    public double radius()         { return radius; }
    public double surfaceGravity() { return surfaceGravity; }

    public double surfaceWeight(double mass) {
        return mass * surfaceGravity;  // F = ma
    }
}

下面是一个简短的程序,根据某个物体在地球上的重量,打印出该物体在所有8颗行星上的重量:

// Takes earth-weight and prints table of weights on all planets (Page 160)
public class WeightTable {
   public static void main(String[] args) {
      double earthWeight = Double.parseDouble(args[0]);
      double mass = earthWeight / Planet.EARTH.surfaceGravity();
      for (Planet p : Planet.values())
         System.out.printf("Weight on %s is %f%n",
                 p, p.surfaceWeight(mass));
   }
}

每个Plant常量都关联了不同的数据,但你有时需要将本质上不同的行为与每个常量关联起来。

第31条:用实例域代替序数

第32条:用EnumSet替代位域

第33条:用EnumMap替代序数索引

第34条:用接口模拟可伸缩的枚举

第35条:注解优先于命名模式

第36条:坚持使用Override注解

第37条:用标记接口定义类型

最近的文章

《Effective Java》读书笔记 第7章 方法

第38条:检查参数的有效性对于公有的方法,要用Javadoc的@throws标签在文档中说明违反参数值会抛出的异常。一旦在文档中记录了对于方法参数的限制,并且记录了一旦违反这些限制将要抛出的异常,强加这些限制就是非常简单的事情了。 /** * Returns a {@code BigIn …

于  , 继续阅读
更早的文章

《Effective Java》读书笔记 第5章 泛型

第23条:请不要在新代码中使用原生态类型声明中具有一个或者多个类型参数(type parameter)的类或者接口就是泛型类或者接口。泛型类和接口统称为泛型(generic type)。 每种泛型定义一组参数化的类型(parameterized type),构成格式为:先是类或者接口的名称,接着用尖 …

于  , 继续阅读
comments powered by Disqus