什么是枚举?
枚举是JDK5引入的新特性。在某些情况下,一个类的对象是固定的,就可以定义为枚举。在实际使用中,枚举类型也可以作为一种规范,保障程序参数安全。枚举有以下特点:
下面是 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; } }
使用建议
开发中使用范围最广的就是利用枚举代替一组静态常量,这种情况可以使用以上注解方式替代。
当枚举还含有其它功能时(如:包含其它定义的方法),则不能替换。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。
本文向大家介绍三十分钟快速掌握C# 6.0知识点,包括了三十分钟快速掌握C# 6.0知识点的使用技巧和注意事项,需要的朋友参考一下 一、只读自动属性(Read-only auto-properties) C# 6之前我们构建只读自动属性: 原理解析:就是编译器在生成set访问器时,它的修饰符是private,由上可知所谓的只读只是针对类外部,在类内部还是可以随意修改属性值的。 C# 6中提供了真
快速枚举是Objective-C的功能,有助于枚举集合。 因此,为了了解快速枚举,我们首先需要了解集合,这将在下一节中进行说明。 Objective-C中的集合 集合是基本结构。 它用于保存和管理其他对象。 集合的整个目的是提供一种有效存储和检索对象的通用方法。 有几种不同类型的集合。 虽然它们都能实现能够容纳其他对象的相同目的,但它们的主要区别在于检索对象的方式。 Objective-C中使用的
主要内容:1. Objective-C集合快速枚举是Objective-C的功能,用于枚举集合。 因此,要了解快速枚举,首先需要了解集合,这将在下一节中进行说明。 1. Objective-C集合 集合是基本结构。它用于保存和管理其他对象。 集合的主要目的是提供一种有效存储和检索对象的通用方法。 有几种不同类型的集合。 虽然它们都能实现能够容纳其他对象的相同目的,但它们的主要区别在于检索对象的方式。 Objective-C中使用的最常见的
你能在Swift中继承枚举吗?关于枚举继承,应该知道哪些规则? 以下测试代码: 产生
本文向大家介绍python命令行工具Click快速掌握,包括了python命令行工具Click快速掌握的使用技巧和注意事项,需要的朋友参考一下 前言 写 Python 的经常要写一些命令行工具,虽然标准库提供有命令行解析工具 Argparse,但是写起来非常麻烦,我很少会使用它。命令行工具中用起来最爽的就是 Click,它是 Flask 的团队 pallets 的开源项目。Click 只要很少的代
本文向大家介绍快速掌握Node.js事件驱动模型,包括了快速掌握Node.js事件驱动模型的使用技巧和注意事项,需要的朋友参考一下 一、传统线程网络模型 在了解Node.js事件驱动模型之前,我们先了解一下传统的线程网络模型,请求进入web服务器(IIS、Apache)之后,会在线程池中分配一个线程来线性同步完成请求处理,直到请求处理完成并发出响应,结束之后线程池回收。 这就会就会带来以下几个问题