zoukankan      html  css  js  c++  java
  • Effective Java 30 Use Enums instead of int constants

    Enumerated type is a type whose legal values consist of a fixed set of constants, such as the seasons of the year.

    // The int enum pattern - severely deficient!

    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;

       

    The basic idea behind Java's enum types is simple: they are classes that export one instance for each enumeration constant via a public static final field.

       

    To associate data with enum constants, declare instance fields and write a constructor that takes the data and stores it in the fields.

       

    Note

    1. unless you have a compelling reason to expose an enum method to its clients, declare it private or, if need be, package-private (Item 13).
    2. If an enum is generally useful, it should be a top-level class; if its use is tied to

      a specific top-level class, it should be a member class of that top-level class (Item22)

    3. Compiler will reminds you that abstract methods in an enum type must be overridden with concrete methods in all of its constants.

         

      /**

      * Demo for enum type use abstract methods for Compile time checking on added enum type.

      */

      package com.effectivejava.EnumAnnotations;

         

      import java.util.HashMap;

      import java.util.Map;

         

      /**

      * @author Kaibo

      *

      */

      public enum Operation {

      PLUS("+") {

      public double apply(double x, double y) {

      return x + y;

      }

      },

      MINUS("-") {

      public double apply(double x, double y) {

      return x - y;

      }

      },

      TIMES("*") {

      public double apply(double x, double y) {

      return x * y;

      }

      },

      DIVIDE("/") {

      public double apply(double x, double y) {

      return x / y;

      }

      };

      private final String symbol;

         

      Operation(String symbol) {

      this.symbol = symbol;

      }

         

      @Override

      public String toString() {

      return symbol;

      }

         

      public abstract double apply(double x, double y);

         

      }

      Note

      Enum types have an automatically generated valueOf(String)method that translates a constant's name into the constant itself. If you override the toString method in an enum type, consider writing a fromString method to translate the custom string representation back to the corresponding enum.

         

      // Implementing a fromString method on an enum type

      private static final Map<String, Operation> stringToEnum = new HashMap<String, Operation>();

      static { // Initialize map from constant name to enum constant

      for (Operation op : values())

      stringToEnum.put(op.toString(), op);

      }

       

    // Returns Operation for string, or null if string is invalid

    public static Operation fromString(String symbol) {

    return stringToEnum.get(symbol);

    }

       

    4. Use nested enum for the strategy enum pattern. Using constant-specific methods.

    /**

    * Demo for the "Using Nested enum for enum strategy pattern."

    */

    package com.effectivejava.EnumAnnotations;

       

    /**

    * @author Kaibo

    *

    */

    // The strategy enum pattern

    enum PayrollDay {

    MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(

    PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY), SATURDAY(

    PayType.WEEKEND), SUNDAY(PayType.WEEKEND);

    private final PayType payType;

       

    PayrollDay(PayType payType) {

    this.payType = payType;

    }

       

    double pay(double hoursWorked, double payRate) {

    return payType.pay(hoursWorked, payRate);

    }

       

    // The strategy enum type

    private enum PayType {

    // constant-specific methods

    WEEKDAY {

    double overtimePay(double hours, double payRate) {

    return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT)

    * payRate / 2;

    }

    },

    WEEKEND {

    double overtimePay(double hours, double payRate) {

    return hours * payRate / 2;

    }

    };

    private static final int HOURS_PER_SHIFT = 8;

       

    abstract double overtimePay(double hrs, double payRate);

       

    double pay(double hoursWorked, double payRate) {

    double basePay = hoursWorked * payRate;

    return basePay + overtimePay(hoursWorked, payRate);

    }

    }

    }

    5. Switches on enums are good for augmenting external enum types with constant-specific behavior.

    // Switch on an enum to simulate a missing method

    public static Operation inverse(Operation op) {

    switch(op) {

    case PLUS: return Operation.MINUS;

    case MINUS: return Operation.PLUS;

    case TIMES: return Operation.DIVIDE;

    case DIVIDE: return Operation.TIMES;

    default: throw new AssertionError("Unknown op: " + op);

    }

    }

    Summary

    Enums are far more readable, safer, and more powerful than int constants. Enums can benefit from associating data with each constant sand providing methods whose behavior is affected by this data. When enums benefit from assocating multiple behaviors with a single method perfer constant-specific methods to enums that switch on their own values. Consider the strategy enum pattern if multiple enum constants share common behaviors.

    作者:小郝
    出处:http://www.cnblogs.com/haokaibo/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    硬件加速器为人工智能应用服务
    js 获取指定字符串个数
    js 仿微信投诉—引入vue.js,拆分组件为单个js
    css 图片波浪效果
    svg path命令
    谷歌浏览器—打断点调试页面
    js 实现加载百分比效果
    js 实现纵向轮播
    css 图片高度自适应
    js 禁止/允许页面滚动
  • 原文地址:https://www.cnblogs.com/haokaibo/p/use-Enums-instead-of-int-constants.html
Copyright © 2011-2022 走看看