枚举

释放双眼,带上耳机,听听看~!
了解枚举

枚举

枚举类型是java 5中新增特性的⼀部分,它被用来将⼀组类似的值包含到⼀种类型当中, 面这种枚举类型的名称则会被定义成独⼀⽆⼆的类型描述符,在这⼀点上和常量的定义相似。 不过相比较常量类型,枚举类型可以为申明的变量提供更⼤的取值范围。

以前定义⼀个常量是在类或接口中声明,比如下面的代码:

public class Color{
   public static final int RED = 0;
   public static final int GREEN = 1;
   public static final int BLACK = 1;
}

但这种方式主要的问题有如下⼏点:

  • 类型不安全: 因为这些常量本质上还是整数,你仍然可以传入任意整数类型的值,这样是可能导致错误的.

  • 一致性差: 因为整形枚举属于编译期常量, 所以编译过程完成后,所有客户端和服务器端引用的地方, 会直接将整数值写入。这样,当你修改旧的枚举整数值后或者增加新的枚举值后, 所有引用地方代码都需要重新编译,否则运行时刻就会出现错误。

  • 类型无指意性:由于颜色枚举值仅仅是⼀些无任何含义的整数值,如果在运行期调试时候, 你就会发现日志中有很多魔术数字,但除了程序员本身,其他人很难明白其奥秘。

基本使用

枚举不仅是简单地将整形数值转换成对象,而是将枚举类型定义转变成⼀个完整功能的类定义。 这种类型定义的扩展允许开发者给枚举类型增加任何方法和属性,也可以实现任意的接口。 另外,自定义的枚举类型默认继承了Enum这个抽象类,此抽象类默认实现 Comparable 和 Serializable 接口。 由于定义的枚举继承了Enum类,会从此类继承⼀些有用的方法,常⻅的方法如下:

  • ordinal:实例方法,返回枚举项的序号,也就是在枚举声明中的序号,第⼀项的值为0,依次递增.

  • name:实例方法,返回枚举常量的名称

  • valueOf:静态方法,依据枚举常量得到对应的枚举对象

  • values:静态方法,返回每⼀个枚举常量代表的枚举对象

public enum Color {
   /**
    * 颜色
    */
   RED("红色"),GREEN("绿色"),BLACK("黑色");

   /**
    * 颜色名称
    */
   private final String colorName;

   Color(String colorName) {
       this.colorName = colorName;
  }

   public String getColorName() {
       return colorName;
  }
}

添加抽象方法或者实现接口

枚举类中可以添加抽象方法,由于每⼀个枚举类型都是final的,所以此抽象方法的实现地方就是枚举类本身,并且每⼀个枚举常量都需要实现此方法。 由于枚举继承于Enum,它是个类,所以其也也可实现接口,让枚举实现接口的⼀种典型用法是利用接口组织各种枚举类型。 例如:

public enum Color {
   /**
    * 颜色
    */
   RED("红色"){
       @Override
       public String getColorRemark(String user) {
           return user + "喜欢红色";
      }
  },GREEN("绿色"){
       @Override
       public String getColorRemark(String user) {
           return user + "喜欢绿色";
      }
  },BLACK("黑色"){
       @Override
       public String getColorRemark(String user) {
           return user + "喜欢黑色";
      }
  };

   /**
    * 颜色名称
    */
   private final String colorName;

   Color(String colorName) {
       this.colorName = colorName;
  }

   public String getColorName() {
       return colorName;
  }

   /**
    * 获取颜色备注的方法
    * @return 颜色备注
    */
   public abstract String getColorRemark(String user);

   /**
    * 方便通过值获取对象
    * @param type 值
    * @return 对象
    */
   public static Color getEnum(String type){
       Color result = null;
       Color[] colors = Color.values();
       for (Color color : colors) {
           if (color.getColorName().equals(type)) {
               result = color;
          }
      }
       MyAssert.isNotNull(result, "Get type: "+type+" Color fails");
       return result;
  }
}

这是一个添加抽象方法的枚举,使用这样的枚举能有效地避免多次if…else或者switch的使用和定义。 接口和抽象方法操作相似。

public class Main {
 private static final String RED_ZH_NAME = "红色";
 private static final String GREEN_ZH_NAME = "绿色";
 public static void main(String[] args) {
   String colorName = "黑色";
   String user = "超人不会飞";
   String value =  Color.getEnum(colorName).getColorRemark(user);
       /*
           value ==> 超人不会飞喜欢黑色
           相当于
           if(RED_ZH_NAME.equals(colorName)) {
               value = user + "喜欢红色";
           }else if (GREEN_ZH_NAME.equals(colorName)){
               value = user + "喜欢绿色";
           }else {
               value = user + "喜欢黑色";
           }
       */
}
}

EnumSet

JDK5.0 中在增加 Enum 类的同时,也增加了两个工具类 EnumSet 和 EnumMap,这两个类都放在 java.util 包中。 EnumSet 是⼀个针对枚举类型的高性能的 Set 接口实现。此类是⼀个抽象类,主要是使⽤其静态方法来操作各种枚举类型, 主要的静态方法如下:

  • range: 创建⼀个包含枚举值中指定范围的枚举对象集合

  • allOf:创建⼀个枚举所有常量值代表的对象集合

  • noneOf: 创建⼀个指定枚举类型的空集合

  • of: 创建⼀个包含方法参数指定的所有元素的集合

  • copyOf: 创建⼀个参数集合中的所有元素的集合

EnumMap

EnumMap 也是⼀个高性能的 Map 接口实现,用来管理使用枚举类型作为 keys 的映射表,并且键不能允许为null。 EnumMap与普通的Map集合使用起来基本差不多,但它是⼀个专⻔高效处理枚举作为键的高效Map集合实现。

Class对象中的枚举

class对象中关于枚举的相关功能主要是getEnumConstants方法与isEnum方法.

  • getEnumConstants方法返回枚举类型的所有元素,如果class对象不是枚举类型返回null,此方法作用类似枚举类型的values方法。

  • isEnum方法用来判断是否是⼀个枚举类型。

使用注意

  1. enum 类型不支持 public 和 protected 修饰符的构造方法,因此构造函数⼀定要是 private 或 friendly的。 也正因为如此,所以枚举对象是无法在程序中通过直接调用其构造方法来初始化的。

  2. 定义 enum 类型时候,如果是简单类型,那么最后⼀个枚举值后不用跟任何⼀个符号; 但如果有定制方法,那么最后⼀个枚举值与后面代码要用分号 ; 隔开,不能用逗号或空格。

  3. 由于 enum 类型的值实际上是通过运行期构造出对象来表示的,所以在 cluster 环境下,每个虚拟机都会构造出⼀个同义的枚举对象。 因而在做比较操作时候就需要注意,如果直接通过使用等号 ( ‘ == ’ ) 操作符,这些看似⼀样的枚举值⼀定不相等,因为这不是同⼀个对象实例。

  4. 枚举类是不能被继承的,因为每⼀个枚举类都是final的

给TA买糖
共{{data.count}}人
人已赞赏
Java教程技术文章

Java-lambda 表达式

2021-9-6 11:49:58

后端开发技术文章资源分享

CodeMirror

2021-9-10 10:57:38

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索