Javajava干货Java学习笔记

Think In Java 第19章 枚举类型

2016-07-31  本文已影响91人  KuTear

本文发表于KuTear's Blog,转载请注明

  1. 默认枚举继承至Enum类,由于Java的单一继承机制,所以不能在继承至别的类.

  2. 枚举中的元素实质为类的类部静态常量域.

    public class EnumTest {
        enum Test {
            TEST_1("1"), TEST_2("2");
            private String descript;
            Test(String descript) {
                this.descript = descript;
            }
        }
    }
    

    该枚举通过反编译查看其内部(javap EnumTest$Test.class),另外,枚举类是final,不会有子类

    Compiled from "EnumTest.java"
    final class EnumTest$Test extends java.lang.Enum<EnumTest$Test> {
        public static final EnumTest$Test TEST_1;
        public static final EnumTest$Test TEST_2;
        public static EnumTest$Test[] values();
        public static EnumTest$Test valueOf(java.lang.String);
        static {};
    }
    
  3. 对于其构造函数,由于不允许用户自行实例化,构造器为privatepublic都是一样的.

  4. 静态导入,如上面的例子.再别的地使用可以使用静态导入

    import static EnumTest.Test.*
    
  5. Javaswitch子句支持的类型

    • short(Short)
    • char(Charactor)
    • byte(Byte)
    • int(Integer)
    • String
    • enum

    在Java7中引入的String本质上也是使用int来做判断的(hashCode()equals())

  6. 枚举的values()静态函数是由编译器写入.向上转型为Enum后丢失.但可以通过ClassgetEnumContants()获取到枚举元素.

  7. 枚举实现抽象方法

    enum FontConstant{
          Blod{
              @Override
              void show() {
                 //TODO
              }
          },
          Italilc{
              @Override
              void show() {
                 //TODO
              }
          },
          Plain{
              @Override
              void show() {
                 //TODO
              }
          };
          abstract void show();
    }
    
  8. EnumSetEnumMap的使用

    • EnumSet
      内部的数据的顺序与add(...)时的顺序没有关系,而是与enum中声明的顺序一致,
    public static void showEnumSet(){
          EnumSet<FontConstant> enumSet = EnumSet.noneOf(FontConstant.class);
          enumSet.add(FontConstant.Blod);
          enumSet.add(FontConstant.Plain);
          enumSet.add(FontConstant.Italilc);
          enumSet.add(FontConstant.Blod);
          for(Iterator<FontConstant> iter = enumSet.iterator(); iter.hasNext();){
              System.out.println(iter.next());
          }
    }
    

    输出:

    Blod
    Italilc
    Plain

    由此可以看见,EnumSet的顺序是与enum的声明有关,并且只能添加不重复的对象

    • EnumMap
      EnumMapEnumSet的顺序是一样的.
  9. 枚举责任链

    实现依赖与枚举的顺序

    enum Handler {
         HANDLER_1 {
             @Override
             boolean handler(Action action) {
                 return action.action == 1;
             }
         },
         HANDLER_2 {
             @Override
             boolean handler(Action action) {
                 return action.action == 2;
             }
         };
    
         abstract boolean handler(Action action);
    }
    
    public static class Action{
         int action;
    
         public Action(int action) {
             this.action = action;
         }
    }
    
    public static void handler(Action action) {
         for (Handler handler : Handler.values()) {
             if (handler.handler(action)) {
                 System.out.println(handler.name() + " Handle This Action");
                 return;
             }
         }
         System.out.println("No One Can Handle");
    }
    
    public static void main(String[] args) {
         Action a1 = new Action(1);
         handler(a1);
         Action a2 = new Action(2);
         handler(a2);
         Action a3 = new Action(3);
         handler(a3);
    }
    

    输出

    HANDLER_1 Handle This Action</br>
    HANDLER_2 Handle This Action</br>
    No One Can Handle

  10. 枚举状态机

    1个事件的完成要经过A->B->C->D四个状态,

    public void process(Status status){
      switch(status.getStatus){
        case A:
           status.setStatus(B);
           break;
        case B:
           status.setStatus(C);
           break;
        ...   
      }
    }
    

    这是使用(if/else)/switch实现,我们还可以使用enum来实现

    enum Status {
        A {
            @Override
            void process(Product pro) {
                pro.status = B;
            }
        },
        B {
            @Override
            void process(Product pro) {
                System.out.println("OK");
                pro.status = C;          //reset
            }
        },
        ...
        abstract void process(Product pro);
    }
    
    public static class Product{
        private Status status = Status.A;
        public void make(){
            status.process(this);
        }
    }
    
    public static void main(String[] args) {
        Product product = new Product();
        for (int i = 0; i < 10; i++) {
            System.out.println(product.status.name());
            product.make();
        }
    }
    
  11. 枚举多路分发

    根据对象的类型而对方法进行的选择,就是分派(Dispatch)。

上一篇下一篇

猜你喜欢

热点阅读