Java> Java核心卷读书笔记 - 枚举类

引例

当一个变量只能在一个有限集合内取值时,可以考虑使用枚举类型。比如,衣服尺寸分别编码为S、M、L、X,如果int数字1~4表示这4个编码,可能会出现一些问题:例如,衣服尺寸变量可能为0或者>4的数字,但是程序可能还不清楚含义。
对于这种情况,可以定义枚举类型,表示衣服尺寸所有可能编码
enum Size{SMALL, MEDIUM, LARGE, EXTRA_LARGE}
声明变量表示一件衣服尺寸为M
Size s = Size.MEDIUM
这样,衣服尺寸就只能是枚举类型的枚举值,没有任何值用null表示。


定义枚举类enum

定义一个枚举类型实际上也是定义一个类,所有枚举类型都继承自Enum类。

public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }

既然枚举类型Size也是类,那是为什么没有构造器、方法和域呢?
因为所有的枚举类都继承自Enum类,子类使用Java编译器提供的缺省构造器。作为枚举类型,主要目的是提供对枚举值的支持,如果单纯使用类的功能,更建议用普通class而非enum。
如果需要使用显示构造器,也是可以的,比如

// 使用构造器的枚举类
public enum Size {
      SMALL("S"),
      MEDIUM("M"),
      LARGE("L"),
      EXTRA_LARGE("XL");

      private String abbreviation; // 名称自定义
      Size(String abbreviation) {
            this.abbreviation = abbreviation;
      }

      public String getAbbreviation() {
            return abbreviation;
      }
}

枚举类型的使用

获取枚举常量名

获取单个枚举常量名
String t = Size.SMALL.toString(); // 获取枚举常量名 'SMALL'

获取所有枚举常量

Size[] values = Size.values(); // values是包含Size.SMALL, Size.MEDIUM, Size.LARGE, Size.EXTRA_LARGE的数组

// 打印每个枚举常量名
for(Size size: values) {
      System.out.println(size);
}

枚举名 -> 枚举常量

从枚举常量名构建枚举变量
Size s = Enum.valueOf(Size.class, "SMALL"); // valueOf是toString逆


比较枚举类型

比较两个枚举类型变量是否相等,使用 “==”,而不要使用“equals”。

Size s1 = Size.MEDIUM;
Size s2 = Size.LARGE;
if(s1 == s2) 
      System.out.println("s1 == s2");
else System.out.println("s1 ≠ s2");

获取枚举常量出现位置

可以利用Enum的orinal()方法获取枚举常量在定义中出现位置。枚举常量位置值从0开始,逐渐递增。
枚举常量值无法通过像C那样通过设置enum{SMALL=1, MEDIUM, LARGE, EXTRA_LARGE}修改,通过API只能获取枚举常量在定义中出现位置顺序,而不能修改枚举值本身的值。

// 枚举类型Size定义
public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }

Size s1 = Size.SMALL;
int a = s1.ordinal(); // a = 0, 对应枚举常量Size.SMALL在定义中的出现顺序

枚举类与单例模式

单例模式需要实现的目标是:创建只有一个实例引用(或指针)共享使用,单例模式3个特点:

  1. 单例类构造方法私有;
  2. 单例类实例变量引用唯一并且私有化;
  3. 单例类提供给其他对象这一私有化实例引用(如getInstance);

单例模式还需要关注的点:

  1. 是否延迟实例化;
  2. 是否多线程安全;

方式一:利用枚举类型直接构造单例类
这种方式利用了枚举类型只会装载一次的特性,等同于饿汉式,虽然线程安全,不过没有延迟实例化。

/**
* 延迟实例化:否
* 多线程安全:是 
*/
public enum User{
      INSTANCE;
      private User() {
      }

      public static  User getInstance() {
            return User.INSTANCE;
      }
}

// 等价于饿汉式
public class User{
      private static User instance = new User();
      private User() {}
      
      public static User getInstance() {
            return instance;
      }
}

方式二:枚举类作为单例类的内部类
利用枚举类只会


参考

  1. 枚举实现单例模式
  2. 菜鸟教程-单例模式
posted @ 2020-12-10 17:55  明明1109  阅读(81)  评论(0编辑  收藏  举报