美文网首页
【Java】enum

【Java】enum

作者: wuchaooooo | 来源:发表于2016-08-09 18:06 被阅读185次

    昨天在做besuper的小型交互游戏的时候,强默默走到我边上,然后看了一眼我的代码,又一如既往的开始喷我:你这写的啥玩意儿啊!这么多类常量定义在前面,干嘛创建一个枚举类型!也就是因为这样被喷的经历,让我今天下决心好好了解一下enum的用法。


    优势

    为什么在有些时候我们要用枚举呢?所以先看看枚举常量和我们经常使用的类常量、实例常量比较,有什么优势。

    1. 枚举常量更加简单
      在接口中定义类常量,如下:
    interface Season {
        int Spring = 0;
        int Summer = 1;
        int Autumn = 2;
        int Winter = 3;
    }
    

    在枚举中定义常量

    public enum Season {
        SPRING, SUMMER, AUTUMN, WINTER;
    }
    

    枚举只需要定义每一个枚举项(其实每个枚举项就是一个枚举类型的实例对象),不需要定义枚举值,而接口常量(即类常量)则必须初始化,否则编译不通过。两个引用方式相同(类名.属性),但是枚举表示的是一个枚举项,字面量就是SPRING、SUMMER、AUTUMN、WINTER,而接口常量字面量是一个int类型:0、1、2、3。

    1. 枚举常量属于稳定型
      如果我们使用一个接口常量,我们就必须要对输入值进行检查,确定是否越界,如果常量非常庞大,校验输入就是一件非常麻烦的事情,但是这个过程又无法避免。
    public void describe(int s) {
      if (s >= 0 && s <= 4) {
        switch(s) {
          case Season.Summer:
            System.out.println("Summer is very hot!");
            break;
          case Season.Winter:
            System.out.println("Winter is very cold!");
            break;
        }
      }
    }
    

    如果是枚举常量,我们看看它是怎么避开校验的。

    public void describe(Season s) {
      switch(s) {
         case Season.Summer:
            System.out.println("Summer is very hot!");
            break;
          case Season.Winter:
            System.out.println("Winter is very cold!");
            break;
      }
    }
    

    因为我们已经限定了输入的参数只能是Season枚举,所以只能输入Season的四个实例。这也是枚举很好的一个作用:在编译期间限定类型,不允许发生越界的情况。

    1. 枚举具有内置方法
      每个枚举都是java.lang.Enum的子类。该基类提供了很多方法:获得排序值得ordinal(),compareTo()等。比如列出所有的枚举值:
    public static void main(String[] args) {
      for (Season s : Season.value()) {
        System.out.println(s);
      }
    }
    
    1. 枚举可以自定义方法
      这一点看上去不是枚举的优点,因为在定义类常量所在的类里面也可以定义方法,但是枚举在可以定义静态方法和实例方法的基础之上,还可以从根本上杜绝枚举常量在别的类中被实例化(因为枚举的构造方法默认是private的,所以只允许在枚举中实例化,不允许在别的地方进行实例化。这也是枚举的意义之一!)。
      枚举实现:
    enum Season {
      SPRING, SUMMER, AUTUMN, WINTER;
    
      public static Season getComfortableSeason() {
        return SPRING;
      }
    }
    

    类实现:

    class Season {
        public final static int Spring = 0;
        public final static int Summer = 1;
        public final static int Autumn = 2;
        public final static int Winter = 3;
    
      public static void int getComfortableSeason() {
        return Spring;
      }
    }
    
    1. 虽然枚举在很多方面都比接口常量和类常量做得好,但是有一点它比不上接口常量和类常量,就是继承。因为枚举是不能被继承的,也就是说一个枚举常量定义之后,除非修改重构,否则无法做扩展。但是,我们依旧要用枚举常量替代接口常量或者类常量

    枚举常量一个很关键的用法

    先定义一个枚举类

    enum Season {
      SPRING, SUMMER, AUTUMN, WINTER;
      }
    }
    

    再定义一个类

    public class chooseSeason {
      String s = "spring";
      Season season = Season.valueOf(s.toUpperCase());
      switch (season) {
        case SPRING :
          System.out.println("这是春天");
        case SUMMER:
          System.out.println("这是夏天");
        case AUTUMN:
          System.out.println("这是秋天");
        case WINTER:
          System.out.println("这是冬天");
      }
    }
    

    这里,我们是想把一个常量传入switch,然后进行一个选择。这里我们运用了枚举的第一个特点,就是switch()里面的参数类型定死为Season枚举类型了。但是,如果我们得到的数据是一个字符串,我们想把这个字符串的字面量当做switch的条件传入怎么办呢?这个时候,我们把字符串变成大写,并通过Enum里面的valueOf()方法,把字符串转成枚举常量。并且这个枚举常量的字面量就是原来字符串的字面量。

    这样的转换在switch里面真的好用

    相关文章

      网友评论

          本文标题:【Java】enum

          本文链接:https://www.haomeiwen.com/subject/ytrdsttx.html