集合 enum 枚举 简介 案例 MD
Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
集合 enum 枚举 简介 案例
目录
Enum 类
这是所有 Java 语言枚举类型的公共基本类。
public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable
构造方法
protected Enum(String name, int ordinal)
单独的构造方法。
- 程序员无法调用此构造方法。
- 该构造方法用于由响应枚举类型声明的编译器发出的代码。
- 参数 name - - 此枚举常量的名称,它是用来声明该常量的标识符。
- 参数 ordinal - - 枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
静态方法
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)
返回带指定名称的指定枚举类型的枚举常量。
- 名称必须与在此类型中声明枚举常量所用的标识符完全匹配。不允许使用额外的空白字符。
- 参数:enumType - 要从中返回常量的枚举类型的 Class 对象
- 参数:name - 要返回的常量名称
- 抛出:
- IllegalArgumentException - 如果指定枚举类型不包含指定名称的常量,或者指定类对象不表示枚举类型
- NullPointerException - 如果 enumType 或 name 为空
另外两个没有在API文档中出现但实际存在的静态方法:
static T valueOf(String name)
返回带指定名称的当前枚举类型的枚举常量。static T[] values()
返回当前枚举类型的枚举常量数组。
新增的方法
Class<E> getDeclaringClass()
返回与此枚举常量的枚举类型相对应的 Class 对象。
- 当且仅当 e1.getDeclaringClass() == e2.getDeclaringClass() 时,两个枚举常量 e1 和 e2 的枚举类型才相同。
- 由该方法返回的值不同于由 Object.getClass() 方法返回的值, Object.getClass() 方法用于带有特定常量的类主体的枚举常量。
String name()
返回此枚举常量的名称,在其枚举声明中对其进行声明。
- 与此方法相比,大多数程序员应该优先考虑使用 toString() 方法,因为 toString 方法返回更加用户友好的名称。
- 该方法主要设计用于特殊情形,其正确性取决于获取正确的名称,其名称不会随版本的改变而改变。
int ordinal()
返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
- 大多数程序员不会使用此方法。它被设计用于复杂的基于枚举的数据结构,比如 EnumSet 和 EnumMap。
Object 中的方法
int compareTo(E o)
比较此枚举与指定对象的顺序。
- 在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。
- 枚举常量只能与相同枚举类型的其他枚举常量进行比较。
- 该方法实现的自然顺序就是声明常量的顺序。
boolean equals(Object other)
当指定对象等于此枚举常量时,返回 true。
protected void finalize()
枚举类不能有 finalize 方法。
- 类 Object 中的 finalize 方法的作用是:当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
int hashCode()
返回枚举常量的哈希码。
String toString()
返回枚举常量的名称,它包含在声明中。
- 它包含在声明中。可以重写此方法,虽然一般来说没有必要。
- 当存在更加“程序员友好的”字符串形式时,应该使用枚举类型重写此方法。
protected Object clone()
throws CloneNotSupportedException 返回此实例的一个副本。
- 如果对象的类不支持 Cloneable 接口,则抛出 CloneNotSupportedException。这可保证永远不会复制枚举,这对于保留其“单元素”状态是必需的。
- 如果对象的类不支持 Cloneable 接口,则重写 clone 方法的子类也会抛出此异常,以指示无法复制某个实例。
关键字 enum
创建枚举类型要使用 enum 关键字,隐含了所创建的类型都是 java.lang.Enum 类的子类。枚举类型符合通用模式 Class Enum<E extends Enum>,而 E 表示枚举类型的名称。枚举类型的每一个值都将映射到 protected Enum(String name, int ordinal) 构造函数中,在这里,每个值的名称都被转换成一个字符串,并且序数设置表示了此设置被创建的顺序。
enum 的语法结构尽管和 class 的语法不一样,但是经过编译器编译之后产生的是一个 class 文件。该 class 文件经过反编译可以看到实际上是生成了一个类,该类继承了 java.lang.Enum。比如:
public enum EnumTest {
MON, TUE;
}
首先编译一下(使用 java 命令),然后直接读取编译后的 EnumTest.class 文件,内容如下:
public enum EnumTest {
MON,
TUE,
private EnumTest() {
}
}
经过反编译之后得到的内容如下:
javap EnumTest.class
Compiled from "EnumTest.java"
public final class test.EnumTest extends java.lang.Enum<test.EnumTest> { //继承自 Enum
public static final test.EnumTest MON;
public static final test.EnumTest TUE;
public static test.EnumTest[] values(); //多了一个 values 方法
public static test.EnumTest valueOf(java.lang.String); //重载了一个 valueOf 方法
static {};
}
所以,实际上 enum 就是一个 class,只不过 java 编译器帮我们做了语法的解析和编译而已。
总结:
可以把 enum 看成是一个普通的 class,它们都可以定义一些属性和方法,不同之处是:enum 不能使用 extends 关键字继承其他类,因为 enum 已经继承了 java.lang.Enum (单一继承)。
测试代码
最简单的定义形式
public enum EnumTest {
MON, TUE, WED, THU, FRI, SAT, SUN; //这段代码实际上调用了7次构造方法 Enum(String name, int ordinal):
}
详细使用案例
public enum EnumTest {
MON, TUE, WED, THU, FRI, SAT, SUN; //这段代码实际上调用了7次构造方法 Enum(String name, int ordinal):
}
给 enum 自定义属性和方法:
enum MyEnum {
MON("bqt1", 1), TUE("bqt2", 2) {
@Override
public String tips() {
return "黑色星期二";
}
},
WED("bqt3", 3) {
@Override
public boolean isBoy() {
return true;
}
},
THU("bqt1", 1);
// 成员变量
public String key;
public int value;
// 构造方法
MyEnum(String key, int value) {
this.key = key;
this.value = value;
}
public String tips() {
return "Nothing";
}
public boolean isBoy() {
return false;
}
}
测试
System.out.println(MyEnum.MON instanceof Enum); // true
System.out.println(MyEnum.valueOf("MON") + " " + Enum.valueOf(MyEnum.class, "MON")); // MON MON
//常用方法
System.out.println(MyEnum.MON.name() + " " + MyEnum.MON.toString()); // MON MON
System.out.println(MyEnum.MON.ordinal() + " " + MyEnum.MON.getDeclaringClass()); // 0 class MyEnum
System.out.println(MyEnum.MON.equals(MyEnum.THU) + " " + MyEnum.MON.compareTo(MyEnum.THU)); // false -3
//给 enum 自定义属性和方法
System.out.println(MyEnum.MON.key + " " + MyEnum.MON.value); // bqt1 1
System.out.println(MyEnum.MON.tips() + " " + MyEnum.TUE.tips()); // Nothing 黑色星期二
System.out.println(MyEnum.MON.isBoy() + " " + MyEnum.WED.isBoy()); // false true
//遍历
MyEnum[] array = MyEnum.values();
System.out.println(Arrays.toString(array)); // [MON, TUE, WED, THU]
for (MyEnum myEnum : MyEnum.values()) {
System.out.print(myEnum.toString() + " "); // MON TUE WED THU
}
在 switch 语句中使用 enum
比如上面的 MyEnum ,如果按下面形式去使用:
MyEnum myEnum = MyEnum.TUE;
switch (myEnum) {
case MyEnum.MON:
break;
case MyEnum.TUE:
break;
default:
break;
}
此时会提示:an enum switch case label must be the unqualified name of an enumeration constant
意思是: 枚举的 switch case 标签必须为枚举常量的非限定名称。
什么意思呢?意思就是 case 语句中只能写枚举类定义的变量名称,不能加类名。
正常代码如下:
MyEnum myEnum = MyEnum.TUE;
switch (myEnum) {
case MON:
break;
case TUE:
break;
default:
break;
}
为什么必须这么写呢?
我们看 官方文档 中对 switch 语句的描述
- If the type of the switch statement’s Expression is an enum type, then every case constant associated with the switch statement must be an enum constant of that type.
- Every case label has a case constant, which is either a constant expression or the name of an enum constant.
- If the type of the switch statement's语句 Expression is an enum type, then every case constant associated with关联的 the switch statement must be an enum constant of that type.
- If the switch statement's Expression is of a reference type引用类型, that is, String or a boxed primitive type or an enum type, then an exception will be thrown will occur if the Expression evaluates to null at run time.
- A Java compiler is encouraged鼓励 (but not required) to provide a warning if a switch on an enum-valued expression lacks缺少 a default label and lacks case labels for one or more of the enum's constants. Such a switch will silently do nothing if the expression evaluates to one of the missing constants.
里面也貌似并没有细说为何不能带限定名。
2018-7-16
集合 enum 枚举 简介 案例 MD的更多相关文章
- LruCache DiskLruCache 缓存 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- protobuf Protocol Buffers 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Javassist 字节码 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- TabLayout ViewPager Fragment 简介 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- - 反编译 AndroidKiller 逆向 实践案例 MD
目录 目录 反编译 AndroidKiller 逆向 实践案例 MD AndroidKiller 简介 插件升级 基本使用 实践案例 修改清单文件 打印 debug 级别的日志 方式一:直接代理 Lo ...
- ThreadLocal 简介 案例 源码分析 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- RxJava RxPermissions 动态权限 简介 原理 案例 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- MySQL字段之集合(set)枚举(enum)
MySQL字段之集合(set)枚举(enum) (2008-12-23 13:51:23) 标签:it 分类:MySQL 集合 SET mysql> create table jihe(f1 ...
- LeakCanary 内存泄漏 监测 性能优化 简介 原理 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
随机推荐
- 【FFT&NTT 总结】
$FFT$总结 (因为还不会啊,,都没做过什么题,所以一边学一边打咯.. 1.主要是用来加速卷积形式的求和吧? $F*G(n)=F[i] × G[n-i]$ 平时是$O(n^2)$的,FFT可以$O( ...
- C语言应用操作之文件
文件是C语言中德中的重点,小编在学习C语言基础知识的时候,大多数的输入输出操作是在屏幕上进行的,现在总算在文件学习上感觉到高大上的样纸.在以前数据量很小时,我们通常将信息从键盘在屏幕上进行输入输出的, ...
- [HDU4123]Bob’s Race
题目大意:给定一棵$n$个点并且有边权的树,每个点的权值为该点能走的最远长度,并输入$m$个询问,每次询问最多有多少个编号连续的点,他们的最大最小点权差小于等于$Q$. 思路:两趟DP(DFS)求出每 ...
- 2010-2011 ACM-ICPC, NEERC, Moscow Subregional Contest Problem I. Interest Targeting 模拟题
Problem I. Interest Targeting 题目连接: http://codeforces.com/gym/100714 Description A unique display ad ...
- Android深入浅出之Binder机制(转)
Android深入浅出之Binder机制 一 说明 Android系统最常见也是初学者最难搞明白的就是Binder了,很多很多的Service就是通过Binder机制来和客户端通讯交互的.所以搞明白B ...
- 使用CefSharp在.Net程序中嵌入Chrome浏览器(八)——Cookie
CEF中的Cookie是通过CookieManager来管理的,可以用它来设置发送的Cookie. 发送Cookie 发送Cookie的一个基本示例如下: var cookieManager = _c ...
- 关于STM32 SPI NSS的讨论
NSS分为内部引脚和外部引脚. NSS外部引脚可以作为输入信号或者输出信号, 输入信号一般用作硬件方式从机的片选, 而输出信号一般用于主SPI去片选与之相连的从SPI. NSS从设备选择有两种模式: ...
- SPI SWD Protocol Implement
//================================================================================= // ARM SWD Mode ...
- OAuth2.0网页授权 提示未关注该测试号
用无高级接口权限的公众号使用别人的appid和appsecret在网页中获取用户信息时,提示未关注该测试号. 搜集各种资料才发现是因为 测试帐号只能对关注者网页授权,正式帐号可以对未关注者授权
- 【Unity 3D】碰撞检测
在unity3d中,能检测碰撞发生的方式有两种, 碰撞器 触发器 概念: (一)碰撞器是一群组件,它包含了很多种类,比如:Box Collider,Capsule Collider等,这些碰撞 ...