三分钟快速掌握Java中枚举(enum)

什么是枚举?

枚举是JDK5引入的新特性。在某些情况下,一个类的对象是固定的,就可以定义为枚举。在实际使用中,枚举类型也可以作为一种规范,保障程序参数安全。枚举有以下特点:

  1. Java中枚举和类、接口的级别相同。
  2. 枚举和类一样,都有自己的属性、方法、构造方法,不同点是:枚举的构造方法只能是private修饰,也就无法从外部构造对象。构造方法只在构造枚举值时调用。
  3. 使用enum关键字声明一个枚举类型时,就默认继承自Java中的 java.lang.Enum类,并实现了java.lang.Seriablizablejava.lang.Comparable两个接口。
  4. 所有的枚举值都是 public static final 的,且非抽象的枚举类不能再派生子类。
  5. 枚举类的所有实例(枚举值)必须在枚举类的第一行显式地列出,否则这个枚举类将永远不能产生实例。
  6. 判断枚举是否相同时,使用 == 和 equals 是一样的。

下面是 java.lang.Enum类中的 equals()

// 这里是final修饰的,不允许子类重写
public final boolean equals(Object other) {
 return this==other;
}

枚举的常用方法

int compareTo(E o)

比较此枚举与指定对象的顺序。在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。 枚举常量只能与相同枚举类型的其他枚举常量进行比较。

// Enum 中的源码
public final int compareTo(E o) {
 Enum other = (Enum)o;
 Enum self = this;
 if (self.getClass() != other.getClass() && // optimization
  self.getDeclaringClass() != other.getDeclaringClass())
  throw new ClassCastException();
 return self.ordinal - other.ordinal;
}

String name()

返回此枚举实例的名称。

static values()

返回一个包含全部枚举值的数组,可以用来遍历所有枚举值。

String toString()

返回此枚举实例的名称,即枚举值。与 name() 一样。

// Enum 中 name() 和 toString()
public String toString() {
 return name;
}
public final String name() {
 return name;
}

int ordinal()

返回枚举值在枚举类中的索引值(从0开始),即枚举值在枚举声明中的顺序,这个顺序根据枚举值声明的顺序而定。

<T extends Enum<T>> valueOf()

返回带指定名称的指定枚举类型的枚举常量,名称必须与在此类型中声明枚举常量所用的标识符完全匹配(不允许使用额外的空白字符)。这个方法与toString相对应,因此重写 toString() 方法,一定要重写 valueOf()方法(我们可以重写 toString() 方法,但不能自己重写 valueOf() 方法,当我们重写 toString()方法时,valueOf() 方法会自动重写,不用我们理会。)

枚举的应用

枚举是一种特殊的类型,其用法和普通的类使用非常相似。

代替一组常量

public enum Color {
 RED, GREEN, BLANK, YELLOW
}

switch 语句中使用

// JDK1.6 中switch加入了对枚举的支持
enum Signal {
 GREEN, YELLOW, RED
} 

...
switch (color) {
 case RED:
  color = Signal.GREEN;
  break;
}
...

向枚举中添加方法

public enum Color { 

 RED("红色"), GREEN("绿色"), BLANK("白色"), YELLO("黄色"); 

 // 成员变量
 private String name;
 // 构造方法
 private Color(String name) {
  this.name = name;
 } 

 // get set 方法
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 } 

}

实现接口

public interface Behaviour {
 void print();
} 

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

 //接口方法
 @Override
 public void print() {
  System.out.println(this.index+":"+this.name);
 }
}

包含抽象方法的枚举类

public enum Operation {

 // 用于执行加法运算
 PLUS { // 花括号部分其实是一个匿名内部子类

  @Override
  public double calculate(double x, double y) {
   return x + y;
  }

 },

 // 用于执行减法运算
 MINUS { // 花括号部分其实是一个匿名内部子类

  @Override
  public double calculate(double x, double y) {
   // TODO Auto-generated method stub
   return x - y;
  }

 },

 // 用于执行乘法运算
 TIMES { // 花括号部分其实是一个匿名内部子类

  @Override
  public double calculate(double x, double y) {
   return x * y;
  }

 },

 // 用于执行除法运算
 DIVIDE { // 花括号部分其实是一个匿名内部子类

  @Override
  public double calculate(double x, double y) {
   return x / y;
  }

 };

 //为该枚举类定义一个抽象方法,枚举类中所有的枚举值都必须实现这个方法
 public abstract double calculate(double x, double y);

}

使用枚举实现单例(单例的最佳实践)

好处:

1.利用的枚举的特性实现单例

2.由JVM保证线程安全

3.序列化和反射攻击已经被枚举解决

public enum Singleton {
 INSTANCE;
 public Singleton getInstance(){
  // 增加这个方法是让别人明白怎么使用,因为这种实现方式还比较少见。
  return INSTANCE;
 }
}

其他关于枚举的使用

EnumSet

range(E from, E to)

从枚举值中获取一段范围的 Set。

for(WeekDayEnum day : EnumSet.range(WeekDayEnum.Mon, WeekDayEnum.Fri)) {
  System.out.println(day);
}

of(E first, E... rest)

创建一个最初包含指定元素的枚举 Set。

noneOf(Class<E> elementType)

创建一个具有指定元素类型的空枚举 Set。

EnumMap

EnumMap(Class<K> keyType)

创建一个具有指定键类型的空枚举Map。

Map<Weather, String> enumMap = new EnumMap<Weather, String>(Weather.class);
enumMap.put(Weather.Sunny, "晴天");
enumMap.put(Weather.Rainy, "雨天");

Android中的枚举

Enum 需要占用较大的内存,如果对内存敏感,请尽量少使用 Enum,换成静态常量。

但是如果不使用枚举,会出现一些安全隐患,所以官方推出了两个注解,可以在编译时期进行类型检查,以此替代枚举。这两个注解分别是:@IntDef 和 @StringDef。位于compile 'com.android.support:support-annotations:+' 。

使用示例

@StringDef的使用与 @IntDef一致,这里以 @IntDef为例。

public interface QRCodeType {

 int WECHAT = 0;
 int ALIPAY = 1;

 @IntDef({WECHAT , ALIPAY })
 @Retention(RetentionPolicy.SOURCE)
 @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
 @interface Checker {

 }

}

public class QRCode {

 @QRCodeType.Checker // 定义在属性
 private int type;

 public void setType(@QRCodeType.Checker int type) { // 定义在参数
  this.type= type;
 }

  @QRCodeType.Checker // 定义在方法(也就是检查返回值的类型)
 public int getType() {
  return type;
 }

}

使用建议

开发中使用范围最广的就是利用枚举代替一组静态常量,这种情况可以使用以上注解方式替代。
当枚举还含有其它功能时(如:包含其它定义的方法),则不能替换。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

(0)

相关推荐

  • 详解Java中的 枚举与泛型

    详解Java中的 枚举与泛型 一:首先从枚举开始说起 枚举类型是JDK5.0的新特征.Sun引进了一个全新的关键字enum来定义一个枚举类.下面就是一个典型枚举类型的定义: public enum Color{ RED,BLUE,BLACK,YELLOW,GREEN } 显然,enum很像特殊的class,实际上enum声明定义的类型就是一个类. 而这些类都是类库中Enum类的子类(Java.lang.Enum).它们继承了这个Enum中的许多有用的方法.我们对代码编译之后发现,编译器将 enu

  • java编程枚举类型那些事!枚举类型定义和重写枚举的方法

    什么是枚举类型 枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中. 而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似.不过相比较常量类型,枚举类型可以为申明的变量提供更大的取值范围. 简单的枚举类型定义 假如你希望创建一个颜色库,你可以这样定义枚举类型 enum Color {red, green, yellow, black}; 然后你就可以使用它 Color T = Color.red; if (T

  • Java枚举的七种常见用法总结(必看)

    用法一:常量 在JDK1.5之前,我们定义常量都是:publicstaticfianl.....现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. Java代码 public enum Color { RED, GREEN, BLANK, YELLOW } 用法二:switch JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强. Java代码 enum Signal { GREEN, YELLOW,

  • Java实现单例模式之饿汉式、懒汉式、枚举式

    单例模式的实现(5种) 常用: 饿汉式(线程安全,调用效率高,但是不能延时加载) 懒汉式(线程安全,调用效率不高,可以延时加载) 其他: 双重检测锁式(由于jvm底层内部模型原因,偶尔会出问题,不建立使用) 静态内部类式(线程安全,调用效率高,但是可以延时加载) 枚举单例(线程安全,调用效率高,不能延时加载) 饿汉式单例具体代码如下: package com.lcx.mode; /** * * 饿汉式单例,不管以后用不用这个对象,我们一开始就创建这个对象的实例, * 需要的时候就返回已创建好的实

  • Java(enum)枚举用法详解

    概念 enum的全称为 enumeration, 是 JDK 1.5 中引入的新特性. 在Java中,被 enum 关键字修饰的类型就是枚举类型.形式如下: enum Color { RED, GREEN, BLUE } 如果枚举不添加任何方法,枚举值默认为从0开始的有序数值.以 Color 枚举类型举例,它的枚举常量依次为RED:0,GREEN:1,BLUE:2 枚举的好处:可以将常量组织起来,统一进行管理. 枚举的典型应用场景:错误码.状态机等. 枚举类型的本质 尽管enum 看起来像是一种

  • 三分钟快速掌握Java中枚举(enum)

    什么是枚举? 枚举是JDK5引入的新特性.在某些情况下,一个类的对象是固定的,就可以定义为枚举.在实际使用中,枚举类型也可以作为一种规范,保障程序参数安全.枚举有以下特点: Java中枚举和类.接口的级别相同. 枚举和类一样,都有自己的属性.方法.构造方法,不同点是:枚举的构造方法只能是private修饰,也就无法从外部构造对象.构造方法只在构造枚举值时调用. 使用enum关键字声明一个枚举类型时,就默认继承自Java中的 java.lang.Enum类,并实现了java.lang.Seriab

  • java 中枚举类enum的values()方法的详解

    java 中枚举类enum的values()方法的详解 前言: 关于枚举,相信使用的已经很普遍了,现在主要写的是枚举中的一个特殊方法,values(), 为什么说特殊呢,因为在Enum 的 API 文档中也找不到这个方法.接下来就看看具体的使用. 理论上此方法可以将枚举类转变为一个枚举类型的数组,因为枚举中没有下标,我们没有办法通过下标来快速找到需要的枚举类,这时候,转变为数组之后,我们就可以通过数组的下标,来找到我们需要的枚举类.接下来就展示代码了. 首先是我们自己的枚举类. public e

  • Java的枚举enum示例详解

    一. 什么是枚举 枚举是一种数据类型,具有集合的一些特点,可以存放多个元素,但存储对象有限且固定,枚举也有比较常见的使用场景,如我们需要表达性别(男.女),颜色(红.黄.蓝),星期(星期一.星期二...星期日),四季(春.夏.秋.冬),地理位置(东.西.南.北),方向(前.后.左.右)等,这些场景都非常适合枚举. 二. 定义枚举 java中使用enum来定义枚举,和class,interface具有同样的等级,(注意是enum,而不是Enum),定义枚举可以有两种情况 第一种:默认构造器(空构造

  • spring boot整合redis实现RedisTemplate三分钟快速入门

    引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> RedisTemplate五种数据结构的操作 redisTemplate.opsForValue(); //操作字符串 redisTemplate.opsForHash();

  • 深入谈谈java的枚举(enum)类型

    前言 在大家日常编程中,往往存在着这样的"数据集",它们的数值在程序中是稳定的,而且"数据集"中的元素是有限的.例如星期一到星期日七个数据元素组成了一周的"数据集",春夏秋冬四个数据元素组成了四季的"数据集".在java中如何更好的使用这些"数据集"呢?因此枚举便派上了用场 枚举其实就是一种类型,跟int, char 这种差不多,就是定义变量时限制输入的,你只能够赋enum里面规定的值. 枚举(enum)实

  • 快速了解Java中NIO核心组件

    背景知识 同步.异步.阻塞.非阻塞 首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下. 同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节). 异步:相对于同步,API调用返回时调用者不知道操作的结果,后面才会回调通知结果. 阻塞:当无数据可读,或者不能写入所有数据时,挂起当前线程等待. 非阻塞:读取时,可以读多少数据就读多少然后返回,写入时,可以写入多少数据就写入多少然后返回. 对于I/O操作,根据Oracle官网的文档,同步异步的划分标准是"调用者是

  • 快速了解Java中ThreadLocal类

    最近看Android FrameWork层代码,看到了ThreadLocal这个类,有点儿陌生,就翻了各种相关博客一一拜读:自己随后又研究了一遍源码,发现自己的理解较之前阅读的博文有不同之处,所以决定自己写篇文章说说自己的理解,希望可以起到以下作用: - 可以疏通研究结果,加深自己的理解: - 可以起到抛砖引玉的作用,帮助感兴趣的同学疏通思路: - 分享学习经历,同大家一起交流和学习. 一. ThreadLocal 是什么 ThreadLocal 是Java类库的基础类,在包java.lang下

  • Java中枚举类型的一种使用方式

    今天改同事的代码发现同事的代码中有大量的if else语句.很不美观而且可读性太差. 因为需要给前端一个key,value的列表.这个列表写死.然而同事的代码. 放几张图,大家自己感受.我都不知道以后这个api咋维护,新增一个工站,减少一个工站. 果然新的任务新增4个工站,好吧,开始给代码装扮一下. 首先,写一个枚举类. package com.smartflow.common.enumpackage; /** * @author :tao * @date :Created in 2020/8/

  • 详解三分钟快速搭建分布式高可用的Redis集群

    这里的Redis集群指的是Redis Cluster,它是Redis在3.0版本正式推出的专用集群方案,有效地解决了Redis分布式方面的需求.当单机内存.并发.流量等遇到瓶颈的时候,可以采用这种Redis Cluster方案进行解决. 分区规则 Redis Cluster采用虚拟槽(slot)进行数据分区,即使用分散度良好的哈希函数把所有键映射到一个固定范围的整数集合里,这里的整数就是槽(slot).Redis Cluster槽的范围是0~16383,计算公式:slot=CRC16(key)

  • Java中枚举的实现原理介绍

    目录 基本概述 使用方式 条件选择 循环遍历 集合映射 常用方法 总结 基本概述 在 JDK1.5 之前,通过定义常量使用的都是:public static fianl.而枚举的设计,就是把相关的常量分组到一个枚举类型里,方便创建和管理. 比如我们要定义一个颜色常量: public enum Colour { RED, YELLOW, BLUE, GREEN } 这段代码通过底层编译后,实际创建了4个枚举对象: new Enum<EnumTest>("RED", 0); n

随机推荐