在项目实际开发过程中,经常会遇到对某些固定的值、字典项的定义的需求,很多项目经常使用常量来定义,其实在jdk1.5就已经引入了枚举,使用枚举可以更好的解决这类需求,本文主要记录枚举的优势以及经常在项目中使用的方法。

知识点

  • 枚举类命名

    枚举类的命名通常需要Enum为后缀,枚举成员名称需要全大写,单词间用下划线隔开。
  • 枚举类不允许使用 extends 关键字

    枚举类默认会继承java.lang.Enum,由于java是单继承,所以在定义枚举类时不允许再继承其他类,但可以实现多个接口
  • 枚举的比较可以直接使用 ==

    枚举是不允许被new出来的,枚举类里的构造函数都限定为私有化,是不允许使用public定义构造函数的。枚举的赋值,如果是同一个元素,则会指向同一个地址,所以是可以直接使用==的,当然在Enum类中,重写了equals方法(如下图),所以也是可以用equals来判断。

  • 枚举常用方法
方法名 用途
name() 返回枚举常量名
toString() 返回枚举常量名
values() 返回枚举成员数组
valueOf() 通过枚举常量名返回枚举
ordinal() 返回枚举常量在enum声明中的位置,位置是从0开始计数的
  • 枚举在switch中的使用

    枚举在switch中的使用,优势在于能控制case的范围(看以下实例),并且在idea中有相关提示
  • 枚举在单例模式的使用

    首先使用枚举类实现单例模式,写法相当简单,看最后的实例;其次枚举是线程安全、单一实例(由于构造方法都是私有的,不能被new)

实例

1. 最简单的枚举

在项目中经常会遇到一些固定值的定义,以往都是用常量来定义,以下用实例说明,为啥枚举的方式优于常量的方式,以下就以季节的定义为例

1.1 使用常量来实现

  1. /**
  2. * @Description: 季节常量定义
  3. */
  4. public class SeasonConst {
  5. /**
  6. * 春季
  7. */
  8. public static final String SPRING = "SPRING";
  9. /**
  10. * 夏季
  11. */
  12. public static final String SUMMER = "SUMMER";
  13. /**
  14. * 秋季
  15. */
  16. public static final String AUTUMN = "AUTUMN";
  17. /**
  18. * 冬季
  19. */
  20. public static final String WINTER = "WINTER";
  21. }

以上实例虽然实现了功能,但有两点比较明显的缺点:

  1. 常量值容易写错(特别是复制黏贴,但是忘记改对应的值,导致系统出bug),idea不会给任何提示。

    比如,某人粗心,在复制黏贴代码时变成(将春季、夏季都定义成春季了):
  1. /**
  2. * 春季
  3. */
  4. public static final String SPRING = "SPRING";
  5. /**
  6. * 夏季
  7. */
  8. public static final String SUMMER = "SPRING";
  1. 如果我想知道一年总共多少个季节,咋整?用常量定义的类,有点捉襟见肘

1.2 使用枚举来实现,可以实现常量的所有功能,并能轻松解决以上提出的常量的两个缺点

  • 定义枚举类SeasonEnum
  1. public enum SeasonEnum {
  2. /**
  3. * 春季
  4. */
  5. SPRING,
  6. /**
  7. * 夏季
  8. */
  9. SUMMER,
  10. /**
  11. * 秋季
  12. */
  13. AUTUMN,
  14. /**
  15. * 冬季
  16. */
  17. WINTER
  18. }

在SeasonEnum枚举类中,如果定义两个 SPRING,编译器会直接报错,很好解决了常量的第一个缺点

  • 该枚举类的使用(1、获取枚举值的名称;2、枚举判断的使用;3、枚举循环的使用。通过枚举的循环,很好解决了常量的第二个缺点;)
  1. //获取枚举值的名称,与toString得到的结果一样
  2. String spring = SeasonEnum.SPRING.name();
  3. System.out.println(spring);
  4. //枚举判断的使用
  5. SeasonEnum springEnum1 = SeasonEnum.SPRING;
  6. SeasonEnum springEnum2 = SeasonEnum.SPRING;
  7. SeasonEnum summerEnum3 = SeasonEnum.SUMMER;
  8. //由于springEnum1、springEnum2都指向SPRING,所以输出true
  9. System.out.println("springEnum1 == springEnum2:" + (springEnum1 == springEnum2));
  10. //由于springEnum1指向SPRING、summerEnum3指向SUMMER,所以输出false
  11. System.out.println("springEnum1 == summerEnum3:" + (springEnum1 == summerEnum3));
  12. //循环枚举,打印枚举类中的所有枚举成员
  13. SeasonEnum[] seasonEnums = SeasonEnum.values();
  14. for (SeasonEnum seasonEnum : seasonEnums) {
  15. System.out.println(seasonEnum.name());
  16. }
  • 枚举在switch中的使用,如果case后跟不存在SeasonEnum类中的枚举(比如 case OTHER),则编译器会报错
  1. String enumName = "SPRING";
  2. SeasonEnum seasonEnum = SeasonEnum.valueOf(enumName);
  3. switch (seasonEnum){
  4. case SPRING:
  5. System.out.println(seasonEnum.name());
  6. break;
  7. case SUMMER:
  8. System.out.println(seasonEnum.name());
  9. break;
  10. case AUTUMN:
  11. System.out.println(seasonEnum.name());
  12. break;
  13. case WINTER:
  14. System.out.println(seasonEnum.name());
  15. break;
  16. default:
  17. System.out.println("other");
  18. }

2.在枚举中使用自定义属性和方法

项目中经常也会遇到一些字典项的定义,比如性别,包含存入数据库中的值,以及显示在页面上的值。以下通过实例来实现性别字典。

  • 定义SexEnum(注意看代码中的注解)
  1. public enum SexEnum {
  2. MAN("man","男"),
  3. WOMEN("women","女");
  4. private String sexCode;
  5. private String sexName;
  6. /**
  7. * 自定义构造函数,以完成枚举对sexCode、sexName赋值
  8. * @param sexCode
  9. * @param sexName
  10. */
  11. SexEnum(String sexCode,String sexName){
  12. this.sexCode = sexCode;
  13. this.sexName = sexName;
  14. }
  15. /**
  16. * 获取sexCode
  17. * @return
  18. */
  19. public String getSexCode() {
  20. return sexCode;
  21. }
  22. /**
  23. * 获取sexName
  24. * @return
  25. */
  26. public String getSexName() {
  27. return sexName;
  28. }
  29. /**
  30. * 项目中经常会根据code,转换成对应的name
  31. * 所以这里自定义方法,根据sexCode获取sexName
  32. * 通过循环enum来实现
  33. * @param sexCode
  34. * @return
  35. */
  36. public static String getSexNameByCode(String sexCode){
  37. String sexName = "sexCode不存在";
  38. SexEnum[] sexEnums = SexEnum.values();
  39. for (SexEnum sexEnum : sexEnums) {
  40. if(sexEnum.getSexCode().equals(sexCode)){
  41. sexName = sexEnum.getSexName();
  42. break;
  43. }
  44. }
  45. return sexName;
  46. }
  47. /**
  48. * 项目中也有根据name,转换成对应的code
  49. * 所以这里自定义方法,根据sexName获取sexCode
  50. * 通过循环enum来实现
  51. * @param sexName
  52. * @return
  53. */
  54. public static String getSexCodeByName(String sexName){
  55. String sexCode = "sexName不存在";
  56. SexEnum[] sexEnums = SexEnum.values();
  57. for (SexEnum sexEnum : sexEnums) {
  58. if(sexEnum.getSexName().equals(sexName)){
  59. sexCode = sexEnum.getSexCode();
  60. break;
  61. }
  62. }
  63. return sexCode;
  64. }
  65. /**
  66. * 根据sexCode获取SexEnum,在switch中使用
  67. * 通过循环enum来实现
  68. * @param sexCode
  69. * @return
  70. */
  71. public static SexEnum getEnumByCode(String sexCode){
  72. SexEnum[] sexEnums = SexEnum.values();
  73. for (SexEnum sexEnum : sexEnums) {
  74. if(sexEnum.getSexCode().equals(sexCode)){
  75. return sexEnum;
  76. }
  77. }
  78. return null;
  79. }
  80. /**
  81. * 重写toString方法
  82. * @return
  83. */
  84. @Override
  85. public String toString() {
  86. return this.sexCode + ":" + this.sexName;
  87. }
  88. }
  • SexEnum枚举类的使用
  1. public class EnumMain {
  2. public static void main(String[] args){
  3. //循环带自定义方法的枚举
  4. SexEnum[] sexEnums = SexEnum.values();
  5. for (SexEnum sexEnum : sexEnums) {
  6. System.out.println("sexCode:"+sexEnum.getSexCode());
  7. System.out.println("sexName:"+sexEnum.getSexName());
  8. System.out.println("sexCode:sexName="+sexEnum.toString());
  9. }
  10. //根据sexCode获取sexName
  11. String sexName = SexEnum.getSexNameByCode("women");
  12. System.out.println("根据sexCode获取sexName:" + sexName);
  13. //根据sexName获取sexCode
  14. String sexCode = SexEnum.getSexCodeByName("男");
  15. System.out.println("根据sexName获取sexCode:" + sexCode);
  16. //通过传入的sexCode使用switch
  17. testSexEnumSwitch("women");
  18. }
  19. /**
  20. * 实际项目中,基本上都是传sexCode的,所以这里也根据传入的sexCode,使用switch方法
  21. * @param sexCode
  22. */
  23. private static void testSexEnumSwitch(String sexCode){
  24. //自定义getEnumByCode方法,通过sexCode获取SexEnum
  25. SexEnum sexEnum = SexEnum.getEnumByCode(sexCode);
  26. switch (sexEnum){
  27. case MAN:
  28. System.out.println(sexEnum.toString());
  29. break;
  30. case WOMEN:
  31. System.out.println(sexEnum.toString());
  32. break;
  33. default:
  34. System.out.println("other");
  35. }
  36. }
  37. }

3.通过枚举实现单例

  • 单例定义
  1. public enum Singleton {
  2. INSTALL;
  3. /**
  4. * 自定义方法
  5. */
  6. public void yourMethod(){
  7. System.out.println("do your business");
  8. }
  9. }
  • 调用方法
  1. Singleton.INSTALL.yourMethod();

源码获取

以上示例都可以通过我的GitHub获取完整的代码,点击获取

Java enum枚举在实际项目中的常用方法的更多相关文章

  1. 简单认识java enum枚举

    什么是枚举 枚举是java5中新增的特性,他是一个特殊的数据类型,他的特殊性在于他既是一种类类型,又比类类型多了安全性,简洁性,便捷性.java枚举类型是功能十分强大齐全的类,功能比其他语言中的对等物 ...

  2. 161208、Java enum 枚举还可以这么用

    在大部分编程语言中,枚举类型都会是一种常用而又必不可少的数据类型,Java中当然也不会例外.然而,Java中的Enum枚举类型却有着许多你意想不到的用法,下面让我们一起来看看. 先来看一段代码示例: ...

  3. Java enum枚举类型

    java的枚举类型详解: 简单示例: public enum Color{ RED,BLUE,BLACK,YELLOW,GREEN } 复杂示例(带自定义构造方法与类型) public enum En ...

  4. Java Enum枚举的用法(转)

    说明:Java的枚举比dotnet的枚举好用,至少支持的方式有很多. 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以 ...

  5. Java Enum 枚举的简单使用

    一.什么是枚举 值类型的一种特殊形式,它从 System.Enum 继承,并为基础基元类型的值提供备用名称.枚举类型有名称.基础类型和一组字段.基础类型必须是一个内置的有符号(或无符号)整数类型(如 ...

  6. (转)java enum枚举

    转载自: 原理:http://singleant.iteye.com/blog/686349 应用:http://www.cnblogs.com/happyPawpaw/archive/2013/04 ...

  7. Java Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)

    示例代码如下: package com.miracle.luna.lambda; import java.util.Arrays; /** * @Author Miracle Luna * @Date ...

  8. java enum(枚举)的使用

    在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的. 例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集” ...

  9. java enum(枚举)使用详解 + 总结

    enum 的全称为 enumeration, 是 JDK 1.5  中引入的新特性,存放在 java.lang 包中. 下面是我在使用 enum 过程中的一些经验和总结,主要包括如下内容: 1. 原始 ...

随机推荐

  1. Python_监测某一个端口是否被占用

    #!/usr/bin/env python# -*- coding:utf-8 -*- import socket, time, threadsocket.setdefaulttimeout(3) # ...

  2. ModelSerializer补充及ListSerializer

    整体单改 路由层.模型层.序列化层不需要做修改,只需要处理视图层:views.py """ 1) 单整体改,说明前台要提供修改的数据,那么数据就需要校验,校验的数据应该在 ...

  3. Automatic Setup of a Humanoid

    The humanoid animation option in Unity 4 makes it possible to retarget the same animations to differ ...

  4. 记忆化dp博弈

    题:http://poj.org/problem?id=2068 题意: 有两个队伍A,B,每个队伍有N个人,交叉坐.即是A(1,3,5,7.....)B(2,4,6,8....).告诉你每个mi(1 ...

  5. Linux 设置开机启动项的几种方法

    方法一:编辑rc.loacl脚本 Ubuntu开机之后会执行/etc/rc.local文件中的脚本. 所以我们可以直接在/etc/rc.local中添加启动脚本. $ vim /etc/rc.loca ...

  6. LIS 问题 二分查找优化

    按n=5,a-{4,2,3,1,5}为例 dp的值依次是: INF INF INF INF INF 4     INF INF INF INF 2     INF INF INF INF 2      ...

  7. Spatial crowdsourcing

    空间众包(Spatial crowdsourcing)分类 空间众包是将一组空间任务众包给一组工作人员的过程,这要求工作人员实际位于该位置以执行相应的任务. 空间众包可以根据员工的动机分为两类:基于奖 ...

  8. hibernate反向工程

  9. 复习break、continue、while、do-while的运用

    一.复习: 循环.反复执行某段语句一种语法形式. 1.基本语法: for( 初始条件 ; 循环条件 ; 状态的改变 ) { 循环体 } 循环的四要素. 循环的执行过程.初始条件--循环条件--循环体- ...

  10. ABB机器人故障处理指南

    ABB工业机器人常见故障处理 1. 开机示教器显示如下   1) 如果机器人开机,示教器一直显示connecting to the robot controller,如上图(robotware版本是白 ...