• 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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    eclipse使用技巧_慕课文章
    如何将MyEclipse开发的项目导入到Eclipse中运行
    毕设笔记记录
    基于百度地图API的运动轨迹追踪软件思想_ldzbook_新浪博客
    Android实现QQ第三方登录
    CentOS 7 单用户模式修改root密码
    linux下su和su
    python升级3.6后 yum出错File "/usr/bin/yum", line 30 ^
    linux基础命令
    网络基础(osi、协议)
  • 原文地址:https://www.cnblogs.com/haokaibo/p/use-Enums-instead-of-int-constants.html
Copyright © 2020-2023  润新知