来源:沉默王二(ID:cmower)


《Java编程思想》中有这么一句话:“有时恰恰因为它,你才能够‘优雅而干净’地解决问题”——这句话说的是谁呢?就是本篇的主角——枚举(Enum)——大家鼓掌了。

在之前很长时间一段时间里,我都不怎么用枚举,因为总感觉它没什么用处——这其实就是“自我认知”的短见。当一个人一直蹲在自己的深井里而不敢跳出来的话,那他真的只能看到井口那么大点的天空

随着时间的推移,我做的项目越来越多,和枚举见面的机会也越来越多,于是我就渐渐地对它越来越有兴趣,研究得多了,才发现原来枚举如此的优秀。

1)枚举的常规用法

一个精简的枚举非常的干净优雅,见下例。

public enum Chenmo {WANGER, WANGSAN, WANGSI
}

我们为沉默枚举创建了三个值,分别是王二、王三、王四。这段代码实际上调用了3次Enum(String name, int ordinal)(ordinal单词的意思为顺序),也就是:

new Enum<Chenmo>("WANGER", 0);
new Enum<Chenmo>("WANGSAN", 1);
new Enum<Chenmo>("WANGSI", 2);

我们来遍历输出一下枚举:

for (Chenmo e : Chenmo.values()) {System.out.println(e);
}
//输出
//WANGER
//WANGSAN
//WANGSI

2)作为switch的判断条件

使用枚举作为switch语句判断条件能让我们的代码可读性更强,示例如下。

Chenmo key = Chenmo.WANGER;
switch (key) {
case WANGSI:System.out.println("今天我送出一个CSDN大鼠标垫");break;
case WANGSAN:System.out.println("今天我被坑一个CSDN学院年卡");break;
default:System.out.println("今天我一边高兴,一边失落");break;
}

在通过case关键字判断的时候,可以直接使用枚举值,非常简洁。另外,在编译期间限定类型,可以有效的避免越界的情况——字符串常量类型在作为switch判断条件的时候很容易因为误写而发生越界问题。

3)枚举实现单例

《Effective Java》一书中对使用枚举实现单例的方式推崇备至:

使用枚举实现单例的方法虽然还没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法。

我觉得“虽然还没有广泛采用”几个字可以去掉了,时至今日,大家应该都知道:使用枚举实现单例是一种非常好的方式。

先来看“双重校验锁”实现的单例:

public class SingleTon2 {// 私有化构造方法private SingleTon2() {};private static volatile SingleTon2 singleTon = null;public static SingleTon2 getInstance() {// 第一次校验if (singleTon == null) {synchronized (SingleTon2.class) {// 第二次校验if (singleTon == null) {singleTon = new SingleTon2();}}}return singleTon;}
}

再来看枚举实现的单例:

public enum SingleTon {INSTANCE;public void method() {System.out.println("我很快乐!");}
}

不比不知道,一比吓一跳啊!枚举方式的单例简单到爆——为了不至于看起来太过精简,我还加了一个输出“我很快乐”的方法。

枚举实现的单例可轻松地解决两个问题:

①、线程安全问题。因为Java虚拟机在加载枚举类的时候,会使用ClassLoader的loadClass方法,这个方法使用了同步代码块来保证线程安全。

②、避免反序列化破坏单例。因为枚举的反序列化并不通过反射实现。

4)枚举可与数据库交互

我们可以配合Mybatis将数据库字段转换为枚举类型。现在假设有一个数据库字段check_type的类型如下:

`check_type` int(1) DEFAULT NULL COMMENT '检查类型(1:未通过、2:通过)',

它对应的枚举类型为CheckType,代码如下:

public enum CheckType {NO_PASS(0, "未通过"), PASS(1, "通过");private int key;private String text;private CheckType(int key, String text) {this.key = key;this.text = text;}public int getKey() {return key;}public String getText() {return text;}private static HashMap<Integer,CheckType> map = new HashMap<Integer,CheckType>();static {for(CheckType d : CheckType.values()){map.put(d.key, d);}}public static CheckType parse(Integer index) {if(map.containsKey(index)){return map.get(index);}return null;}
}

CheckType枚举类比我们刚开始见到的那个Chenmo枚举类要复杂一些。

第一,CheckType新添加了构造方法,还有两个字段,key为int型,text为String型。

第二,CheckType中有一个public static CheckType parse(Integer index)方法,可将一个Integer通过key的匹配转化为枚举类型。

那么现在,我们可以在Mybatis的配置文件中使用typeHandler将数据库字段转化为枚举类型。

<resultMap id="CheckLog" type="com.entity.CheckLog"><id property="id" column="id"/><result property="checkType" column="check_type" typeHandler="com.CheckTypeHandler"></result>
</resultMap>

其中checkType字段对应的类如下:

public class CheckLog implements Serializable {private String id;private CheckType checkType;public String getId() {return id;}public void setId(String id) {this.id = id;}public CheckType getCheckType() {return checkType;}public void setCheckType(CheckType checkType) {this.checkType = checkType;}
}

CheckTypeHandler转换器的类源码如下:

public class CheckTypeHandler extends BaseTypeHandler<CheckType> {@Overridepublic CheckType getNullableResult(ResultSet rs, String index) throws SQLException {return CheckType.parse(rs.getInt(index));}@Overridepublic CheckType getNullableResult(ResultSet rs, int index) throws SQLException {return CheckType.parse(rs.getInt(index));}@Overridepublic CheckType getNullableResult(CallableStatement cs, int index) throws SQLException {return CheckType.parse(cs.getInt(index));}@Overridepublic void setNonNullParameter(PreparedStatement ps, int index, CheckType val, JdbcType arg3) throws SQLException {ps.setInt(index, val.getKey());}
}

CheckTypeHandler 的核心功能就是调用CheckType枚举类的parse()方法对数据库字段进行转换。

5)枚举会比静态常量更消耗内存吗?

说完枚举最常用的4个知识点后,我们来讨论一下“枚举会比静态常量更消耗内存吗?”这个话题——知乎上有人问这样的问题,还有很多人参与回答。

按我的理解,问这个问题的人就好像是在问“0.000,001”比“0.000,000,99”大吗?你说是吗?

Java枚举:小小enum,优雅而干净相关推荐

  1. java的枚举类型是什么_什么是枚举(java枚举类型enum用法)

    最佳回答 枚举 1.枚举 (enumeration) 值类型的一种特殊形式,它从 System.Enum 继承,并为基础基元类型的值提供备用名称.枚举类型有名称.基础类型和一组字段.基础类型. &qu ...

  2. java枚举类型enum用法和写法

    java枚举类型enum用法,enum的全称为 enumeration, 是 JDK 1.5 中引入的新特性,存放在 Java.lang 包中,在上面的这种情况下,enum就能派上用场了.枚举类型的用 ...

  3. java 枚举类型enum的用法详解

    Java Enum原理 public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }; 实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要 ...

  4. Java 枚举(enum)详解

    概念: Java1.5发行版本中增加了新的引用类型--枚举类型(enum type).枚举类型是指由一组固定的常量组成合法值的类型.在Java虚拟机中,枚举类在进行编译时会转变成普通的Java类. 创 ...

  5. java 枚举(enum) 详细用法

    用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...

  6. Java枚举类型(enum)详解

    文章目录 理解枚举类型 枚举的定义 枚举实现原理 枚举的常见方法 Enum抽象类常见方法 编译器生成的Values方法与ValueOf方法 枚举与Class对象 枚举的进阶用法 向enum类添加方法与 ...

  7. 【转】掌握java枚举类型(enum type)

    原文网址:http://iaiai.iteye.com/blog/1843553 1   背景 在java语言中还没有引入枚举类型之前,表示枚举类型的常用模式是声明一组具有int常量.之前我们通常利用 ...

  8. java枚举类Enum入门理解

    目录 枚举的定义 JDK5.0之前只能自定义枚举类 自定义枚举类的理解: JDK5.0之后enum关键字定义枚举类 区别于自定义枚举类 enum的父类Enum的常用方法 toString方法和valu ...

  9. 深度学习Java枚举(enum)——枚举虽小,五脏俱全

    文章目录 深入理解Java枚举 一.什么是枚举 1.1 什么是枚举? 1.2 Java中的枚举类 二.Java枚举的语法 三.Java枚举类的使用规则和应用场景 3.1 Java枚举类的使用规则 3. ...

  10. java 枚举类型enum ppt,关于JAVA枚举类使用的异常

    当前位置:我的异常网» J2SE » 关于JAVA枚举类使用的异常 关于JAVA枚举类使用的异常 www.myexceptions.net  网友分享于:2013-01-24  浏览:5次 关于JAV ...

最新文章

  1. [Android]为指定的应用创建桌面快捷方式
  2. malloc和free实现的原理
  3. 计算机高层应用,计算机网络中高层应用.ppt
  4. 【C++深度剖析教程38】类模板深度剖析
  5. 操作系统真实的虚拟内存是什么样的
  6. Delphi2010
  7. 计算机学术论文3000字,计算机学术论文3000字_计算机学术毕业论文范文模板.doc...
  8. html文件如何显示大纲视图,如何使用大纲视图生成章节目录
  9. 猫咪APP 服务器不稳定,这下知道猫咪为啥经常情绪不稳定了不?
  10. 杨强教授漫谈《西部世界》、生成式对抗网络及迁移学习
  11. 基于Java的qq截图工具设计开发(含源文件)
  12. 网络控制播放器(局域网内通过TCP和UDP控制视频播放器)
  13. 网卡MAC地址(物理地址)映射为IPv6接口标识符
  14. java presentation
  15. 《中国通史》纪录片100集笔记(持更)
  16. MySQL索引(详细,1万字长文)
  17. error LINK:1181 无法打开lib文件
  18. 2021英伟达暑期实习面经(芯片设计)
  19. Oracle 12C OEM 安装
  20. 基于matlab的水轮机调速系统,水轮机调节系统的MATLAB仿真模型.PDF

热门文章

  1. C语言面试基础知识整理
  2. python 星号*使用方法
  3. 【Stimulsoft Reports Flex教程】从代码渲染报表
  4. Angular js 具体应用(一)
  5. transform插件
  6. 笔记本Wifi连接出现“设置与网络连接不匹配”的解决方法
  7. DataTable的AcceptChange方法为什么不能在Update之前?
  8. 【推荐】如何删除windows服务
  9. Linux中利用RAW SOCKET直接通过网卡收发数据
  10. 几个Python运算符