转载 java枚举类型enum的使用 (原文地址:http://blog.csdn.net/wgw335363240/article/details/6359614)
java枚举类型enum的使用
最近跟同事讨论问题的时候,突然同事提到我们为什么java中定义的常量值不采用enmu枚举类型,而采用public final static 类型来定义呢?以前我们都是采用这种方式定义的,很少采用enum定义,所以也都没有注意过,面对突入起来的问题,还真有点不太清楚为什么有这样的定义。既然不明白就抽时间研究下吧。
Java中的枚举类型采用关键字enum来定义,从jdk1.5才有的新类型,所有的枚举类型都是继承自Enum类型。要了解枚举类型,建议大家先打开jdk中的Enum类简单读一下,这个类里面定义了很多protected方法,比如构造函数,如果要使用这些方法我们可以把枚举类型定义到当前类中。每个枚举类型,都有自己的名字和顺序,当我们输出一个枚举类型的时候,会输入枚举类型的name,具体可以参考下面的例子。
一、 通常定义常量方法
我们通常利用public final static方法定义的代码如下,分别用1表示红灯,3表示绿灯,2表示黄灯。
package com.csdn.myEnum; public class Light { /*红灯*/ public final static int RED=1; /*绿灯*/ public final static int GREEN=3; /*黄灯*/ public final static int YELLOW=2; } |
二、 枚举类型定义常量方法
枚举类型的简单定义方法如下,我们似乎没办法定义每个枚举类型的值。比如我们定义红灯、绿灯和黄灯的代码可能如下:
public enum Light { RED, GREEN, YELLOW; } |
我们只能够表示出红灯、绿灯和黄灯,但是具体的值我们没办法表示出来。别急,既然枚举类型提供了构造函数,我们可以通过构造函数和覆写toString方法来实现。首先给Light枚举类型增加构造方法,然后每个枚举类型的值通过构造函数传入对应的参数,同时覆写toString方法,在该方法中返回从构造函数中传入的参数,改造后的代码如下:
public enum Light { //利用构造函数传参 RED(1), GREEN(3), YELLOW(2); // 定义私有变量 private int nCode; // 构造函数,枚举类型只能为私有 private Light(int _nCode) { this.nCode = _nCode; } @Override public String toString() { return String.valueOf(this.nCode); } } |
三、 完整示例代码
枚举类型的完整演示代码如下:
package com.csdn.myEnum; import java.util.EnumMap; import java.util.EnumSet; public class LightTest { // 1.定义枚举类型 public enum Light { //利用构造函数传参 RED(1), GREEN(3), YELLOW(2); // 定义私有变量 private int nCode; // 构造函数,枚举类型只能为私有 private Light(int _nCode) { this.nCode = _nCode; } @Override public String toString() { return String.valueOf(this.nCode); } } /** * @param args */ public static void main(String[] args) { // 1.遍历枚举类型 System.out.println("演示枚举类型的遍历 ......"); testTraversalEnum(); // 2.演示EnumMap对象的使用 System.out.println("演示EnmuMap对象的使用和遍历....."); testEnumMap(); // 3.演示EnmuSet的使用 System.out.println("演示EnmuSet对象的使用和遍历....."); testEnumSet(); } /** * 演示枚举类型的遍历 */ private static void testTraversalEnum() { Light[] allLight = Light.values(); for (Light aLight : allLight) { System.out.println("当前灯name:" + aLight.name()); System.out.println("当前灯ordinal:" + aLight.ordinal()); System.out.println("当前灯:" + aLight); } } /** * 演示EnumMap的使用,EnumMap跟HashMap的使用差不多,只不过key要是枚举类型 */ private static void testEnumMap() { // 1.演示定义EnumMap对象,EnumMap对象的构造函数需要参数传入,默认是key的类的类型 EnumMap<Light, String> currEnumMap = new EnumMap<Light, String>( Light.class); currEnumMap.put(Light.RED, "红灯"); currEnumMap.put(Light.GREEN, "绿灯"); currEnumMap.put(Light.YELLOW, "黄灯"); // 2.遍历对象 for (Light aLight : Light.values()) { System.out.println("[key=" + aLight.name() + ",value=" + currEnumMap.get(aLight) + "]"); } } /** * 演示EnumSet如何使用,EnumSet是一个抽象类,获取一个类型的枚举类型内容<BR/> * 可以使用allOf方法 */ private static void testEnumSet() { EnumSet<Light> currEnumSet = EnumSet.allOf(Light.class); for (Light aLightSetElement : currEnumSet) { System.out.println("当前EnumSet中数据为:" + aLightSetElement); } } } |
执行结果如下:
演示枚举类型的遍历 ...... 当前灯name:RED 当前灯ordinal:0 当前灯:1 当前灯name:GREEN 当前灯ordinal:1 当前灯:3 当前灯name:YELLOW 当前灯ordinal:2 当前灯:2 演示EnmuMap对象的使用和遍历..... [key=RED,value=红灯] [key=GREEN,value=绿灯] [key=YELLOW,value=黄灯] 演示EnmuSet对象的使用和遍历..... 当前EnumSet中数据为:1 当前EnumSet中数据为:3 当前EnumSet中数据为:2 |
四、 通常定义常量方法和枚举定义常量方法区别
以下内容可能有些无聊,但绝对值得一窥
- 代码:
public class State {
public static final int ON = 1;
public static final Int OFF= 0;
}
有什么不好了,大家都这样用了很长时间了,没什么问题啊。
首先,它不是类型安全的。你必须确保是int
其次,你还要确保它的范围是0和1
最后,很多时候你打印出来的时候,你只看到 1 和0 ,
但其没有看到代码的人并不知道你的企图,抛弃你所有旧的public static final常量吧
- 可以创建一个enum类,把它看做一个普通的类。除了它不能继承其他类了。(java是单继承,它已经继承了Enum),
可以添加其他方法,覆盖它本身的方法
- switch()参数可以使用enum了
- values()方法是编译器插入到enum定义中的static方法,所以,当你将enum实例向上转型为父类Enum是,values()就不可访问了。解决办法:在Class中有一个getEnumConstants()方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有的enum实例
- 无法从enum继承子类,如果需要扩展enum中的元素,在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组。达到将枚举元素进行分组。
- 使用EnumSet代替标志。enum要求其成员都是唯一的,但是enum中不能删除添加元素。
- EnumMap的key是enum,value是任何其他Object对象。
- enum允许程序员为eunm实例编写方法。所以可以为每个enum实例赋予各自不同的行为。
- 使用enum的职责链(Chain of Responsibility) .这个关系到设计模式的职责链模式。以多种不同的方法来解决一个问题。然后将他们链接在一起。当一个请求到来时,遍历这个链,直到链中的某个解决方案能够处理该请求。
- 使用enum的状态机
- 使用enum多路分发
转载 java枚举类型enum的使用 (原文地址:http://blog.csdn.net/wgw335363240/article/details/6359614)的更多相关文章
- OpenSessionInViewFilter 的配置及作用(原文地址: http://blog.csdn.net/sunsea08/article/details/4545186)
spring为我们解决hibernate的Session的关闭与开启问题. Hibernate 允许对关联对象.属性进行延迟加载,但是必须保证延迟加载的操作限于同一个 Hibernate Sessio ...
- 联想笔记本 thinkpad BIOS 超级密码 Supervisor Password 清除 破解 亲测有效 转载地址https://blog.csdn.net/ot512csdn/article/details/72571674
联想笔记本 thinkpad BIOS 超级密码 Supervisor Password 清除 破解 亲测有效 转载地址https://blog.csdn.net/ot512csdn/article/ ...
- .net反射详解 原文://http://blog.csdn.net/wenyan07/article/details/27882363
概述反射 通过反射可以提供类型信息,从而使得我们开发人员在运行时能够利用这些信息构造和使用对象. 反射机制允许程序在执行过程中动态地添加各种功能. 运行时类型标识 运行时类型标识(RTTI),可以在程 ...
- 笔记1:jmeter性能测试使用示例(原文:http://blog.csdn.net/zhongweijian/article/details/7619319)
jmeter是一个简单开源的纯java的性能测试工具.今天学习了jmeter使用了下jmeter,使用起来非常简单. 如果我们要对163的首页性能进行简单测试,我们可以按照以下步骤进行. 1.在测试计 ...
- git中利用rebase来压缩多次提交 ----- 原文:https://blog.csdn.net/itfootball/article/details/44154121
之前我们用git merge –squash来将分支中多次提交合并到master后,只保留一次提交历史.但是有些提交到github远程仓库中的commit信息如何合并呢? 使用下面的命令,最后一个数字 ...
- 【转】java枚举类型enum的使用
原文网址:http://blog.csdn.net/wgw335363240/article/details/6359614 java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到 ...
- 数组中&a与&a[0]的区别 转载自http://blog.csdn.net/FX677588/article/details/74857473
在探讨这个问题之前,我们首先来看一道笔试题,如下: [摘自牛客网]下列代码的结果是:(正确答案是 C) main() { int a[5]={1,2,3,4,5}; int *ptr=(int *)( ...
- MVC和WebApi 使用get和post 传递参数。 转载https://blog.csdn.net/qq373591361/article/details/51508806
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/qq373591361/article/details/51508806我们总结一下用js请求服务器的 ...
- 爬虫出现Forbidden by robots.txt(转载 https://blog.csdn.net/zzk1995/article/details/51628205)
先说结论,关闭scrapy自带的ROBOTSTXT_OBEY功能,在setting找到这个变量,设置为False即可解决. 使用scrapy爬取淘宝页面的时候,在提交http请求时出现debug信息F ...
随机推荐
- (转)发现两个有用的C函数_alloca()、_msize()
转自: http://blog.csdn.net/pony12/article/details/8678071 (1)_alloca()alloca也是用来分配存储空间的,它和malloc的区别是它是 ...
- zz[C++]合理的设计和使用消息队列
http://www.cnblogs.com/egmkang/archive/2012/11/17/2763295.html 生产者消费者问题,是永远的经典. 单纯让多个线程去竞争,占有资源然后处理, ...
- 【转】mysql行列转换方法总结
转:http://blog.chinaunix.net/uid-7692530-id-2567582.html 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解 ...
- 向Oracle数据库中CLOB插入数据报错问题
今天在项目中向数据库的CLOB属性插入一段篇文章(1000~2000)字就会报一个字符串过长的错误. 网上说用流来处理,没有这么做.这像是一个Bug,只要把插入的数据,默认扩充到2000以上就ok了. ...
- pat_1
2-0 2-1 #include <stdio.h> int main() { int inch,foot,cm; scanf("%d",&cm); foot= ...
- android的数据存储方式
数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 ...
- 设计师如何为 Android 应用标注尺寸
http://blog.cutterman.cn/?p=33 1. 画布大小定位 720 x 1280,72 dpi2. 只使用偶数单位的尺寸,比如 96 px 的列表项高度,16 px 的边距,64 ...
- A Survey of Dynamic Spectrum Access
这是2007年IEEE Signal Process 杂志上的一篇文章.综述DSA的.正如文章最后所说,DSA/OSA(Opportunity Spectrum Access)还处于襁褓期,在技术.政 ...
- MyEclipse中新建JSP(Advanced Template)文件时自动生成的
<meta http-equiv="pragma" content="no-cache"> <meta http-equiv="ca ...
- tcp/心跳包
1,http://blog.csdn.net/yuzhiyuxia/article/details/7857508 心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时 ...