• Java(7)-枚举


    参考:java技术手册

    参考:https://blog.csdn.net/testcs_dn/article/details/78604547

    java有两种特殊形式的类型,在java类型系统中扮演着特定的角色。这两种类型是枚举类 型(enumerated type)和注解类型(annotation type)。

    本文介绍枚举。

    一、枚举的定义
    枚举是类的变种。

    假设我们要定义红、黄、蓝色中颜色的枚举,我们可以使用enum关键字定义这个类型:

    public enum PrimaryColor {
      // 实例列表末尾的分号是可选的
      RED, GREEN, BLUE
    }

    注意:
    (1)如上PrimaryColor定义的是一个类型,这个类型是枚举。

    (2)枚举内部的REG、GREEN、BLUE实际上是PrimaryColer类型的实例

    通过如下包含成员的枚举类型定义,更好的理解枚举实例的概念:

      Java中由于枚举是特殊的类,所以可以拥有成员(字段和方法)

      假设,我们要定义一个枚举,包含前几个正多边形(等边等角的形状),而且想为这些形状指定一些属性(在方法中指定)。我们可以使用接收一个参数的枚举实现这个需求,如下所示:

      public enum RegularPolygon {
        // 有参数的枚举必须使用分号。由于这些实际上是RegularPolygon的实例,所以可以传入 “构造方法 参数。
        TRIANGLE(3), SQUARE(4), PENTAGON(5), HEXAGON(6);

        private Shape shape;

        public Shape getShape() {
          return shape;
        }

        private RegularPolygon(int sides) {
          switch (sides) {
            case 3:
              // 假设这些形状的构造方法接收的参数是边长和角度
              shape = new Triangle(1,1,1,60,60,60);
              break;
            case 4:
              shape = new Rectangle(1,1);
              break;
            case 5:
              shape = new Pentagon(1,1,1,1,1,108,108,108,108,108);
              break;
            case 6:
              shape = new Hexagon(1,1,1,1,1,1,120,120,120,120,120,120);
              break;
            }
          }
        }

      注意,如上:

      (1)如果字段或方法有主体,那么实例列表后面必须加上分号。 

      (2)如上样例中,枚举实例(TRIANGLE、SQUARE、PENTAGON、HEXAGON)具有参数,所以要显式提供构造函数。枚举实例由Java运行时创建,在创建TRIANGLE、SQUARE、PENTAGON、HEXAGON实例时,调用RegularPlygon ()构造方法,分别传入2、4、5、6入参,为这几个枚举实例分配内存空间和赋值。本质上每个枚举实例包含一个shape字段和2个方法。

      (3)枚举实例由Java运行时创建,其不可在枚举外部进行实例化,所以把构造方法声明为私有方法

      (4)枚举有如下特殊性:

        • 都(隐式)扩展 java.lang.Enum 类;(所以不可继承其他类)

        • 不能泛型化;

        • 可以实现接口;

        • 不能被扩展子类

        • 只能有一个私有(或使用默认访问权限)的构造方法

        • 所有的枚举值默认都是 public static final 的。

    二、枚举引入的版本

    enum类型是java1.5引入的。

      

    三、枚举类型的使用

    (1)类似常量的方式使用

      支持枚举之前,常量只能通过public static fianl方式定义。

           引入枚举后,可以使用枚举实现类似常量方式的代码使用。如:

      public enum PrimaryColor {
        // 实例列表末尾的分号是可选的
        RED, GREEN, BLUE
      }

           PrimaryColor类型的REG、GREEN、BLUE实例可以按照静态字段的方式引用:PrimaryColor.RED、PrimaryColor. GREEN 和 PrimaryColor.BLUE。

    (2)配合switch使用
          如:

      enum Signal {
        GREEN, YELLOW, RED
      }


      public class TrafficLight {
        Signal color = Signal.RED;
        

        public void change() {
          switch (color) {
            case RED:
              color = Signal.GREEN;
              break;
            case YELLOW:
              color = Signal.RED;
              break;
            case GREEN:
              color = Signal.YELLOW;
              break;
          }
        }
      }

    (3)配合for循环遍历枚举中的实例

      private enum SimpleEnum {
        SPRING, SUMMER, AUTUMN, WINTER
      }

      public class EnumTest {
        /**
        * 循环枚举,输出ordinal属性;若枚举有内部属性,则也输出。(说的就是我定义的TYPE类型的枚举的typeName属性)
        */
        private static void forEnum() {
          for (SimpleEnum simpleEnum : SimpleEnum.values()) {
            System.out.println(simpleEnum + " ordinal " + simpleEnum.ordinal());
          }
        }
      }

      打印结果是:

      SPRING ordinal 0

      SUMMER ordinal 1

      AUTUMN ordinal 3

      WINTER ordinal 4

           注:

          (1)如上ordinal是继承自 java.lang.Enum 类的int类型字段

          (2)如上println打印中simpleEnum参数会自动调用java.lang.Enum类型从Object中继承的toString()方法转换。

          (3)Java编译器自动在enum类型中插入一些方法,其中就包括values()。所以在enum类型中并没有实现values()方式,程序在没编译的时候,自然就没法查看values()方法的源码。

    (4)枚举中自定义方法、和覆盖继承自enum类型的方法

            enum类型本质上是类,可以自定义方法和覆盖继承的方法。

      public enum Color {
        RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);


        // 成员变量
        private String name;
        private int index;


        // 构造方法
        private Color(String name, int index) {
          this.name = name;
          this.index = index;
        }


        // 普通方法
        public static String getName(int index) {
          for (Color c : Color.values()) {
            if (c.getIndex() == index) {
              return c.name;
            }
          }
          return null;
        }


        // get set 方法
        public String getName() {
          return name;
        }

        public void setName(String name) {
          this.name = name;
        }
        public int getIndex() {
          return index;
        }
        public void setIndex(int index) {
          this.index = index;
        }

        

         @Override  

        public String toString() { 

          returnthis.index+"_"+this.name;  

        }  

      }

      public class EnumTest { 

        ......
        private static void forEnum() {
          for (Color color : Color.values()) {
            System.out.println("color = " + color + " color.name = " + color.getName() + " color.index = " + color.getIndex());
          }
        }
        ......
      }

    (5)枚举实例的比较

     枚举本质上是类型,枚举实例本质上是对象。所以枚举类型对象之间的比较也采用equals方法。但是呢,同class类型对象的不同是,==在class类型的比较中实际上比较的是两个引用是否指向同一对象;==在做枚举类型对象比较时,是比较对象的值是否相等,可替代equals()方法

    (6)枚举可以通过implements关键字继承接口

          使用方式同class继承接口。

    (7)枚举集合

           java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。关于这个两个集合可以参考JDK文档。

  • 相关阅读:
    linux 免密登录
    mysql 重置从库
    elasticsearch原理及简介
    多线程编程--心得
    为什么我们做分布式使用Redis?
    JAVA-JVM调优
    JAVA-JVM调优标志
    Spirng-Mvc之Servlet篇
    Agent Job代理 执行SSIS Package
    Python之爬虫的理解
  • 原文地址:https://www.cnblogs.com/yickel/p/12783463.html
Copyright © 2020-2023  润新知