- 浏览: 367173 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (225)
- java (76)
- English (2)
- office (2)
- 架构设计 (1)
- 人在职场 (3)
- database (21)
- C# (18)
- 向往的院校 (0)
- C++ (1)
- AJAX (1)
- 操作系统 (8)
- eclipse (1)
- Spring (0)
- Linux (1)
- Javascript (6)
- 离散 (0)
- 协议 (1)
- sql server (5)
- sql server (0)
- fdf (0)
- xml (1)
- sql语句里top和distinct一起用 (1)
- 正则表达式 (7)
- 表达 (1)
- ms server (1)
- SWFObject (0)
- 线程 (2)
- Java线程 (0)
- Android & SQLite (0)
- Android (0)
- window.XMLHttpRequest (0)
- DB pool (0)
- tomcat内存溢出设置JAVA_OPTS (1)
- java bcp (1)
- 文件系统转换 (1)
- Microsoft XMLDom (1)
- tree (0)
- C# installer (0)
- 对付http cc攻击 (0)
- Ckeditor (0)
- MyEclipse (0)
- PDM (0)
- PDM OOM (0)
- asp.net (0)
- tomcat (1)
- Tomcat session (1)
- jdk (0)
- Bootstrap (0)
最新评论
-
kenail:
格式太乱了。
转 使用WebService压缩传输的心得 -
存在即为合理:
写得好乱,但是还是谢谢你的驱动
JDBC连接SQL server 2005 驱动 -
guji528:
长见识了,谢谢分享!
TL1协议(正文信息收集整理来源Internet) -
王大人:
Js window confirm()方法及其使用 -
Eastman:
SqlServer附加数据库出错,错误代码5123
转自 http://www.java3z.com 〖 作者:中华风筝 〗
到目前为止,我们仅仅使用了最简单的语法定义枚举类型,其实枚举类型可以做更多的事情,在Tiger的定义中,枚举是一种新的类型,允许用常量来表示特定的数据片断,它能胜任普通类的大部分功能,如定义自己的构造函数、方法、属性等等。这也是Java与C/C++或是Pascal中不同的地方,在那两种语言中枚举类型代表的就是一些int类型的数字,但在Java中枚举更像是一个类。
接下来我们将丰富一下我们的枚举类型。
前面定义了包含五个工作日的枚举类型,但是真正在每个工作日进行操作的动作是在其它类中的printWeekDay方法中进行的。假设我们经过分析发现对工作日的操作应该属于枚举类型WeekDay的职责,那我们就可以把枚举类型改造如下:
Java代码 |
public enum WeekDay { MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY;
/** * 根据工作日的不同打印不同的信息。 */ public void printWeekDay(){ switch(this){ case MONDAY: System.out.println(“Today is Monday!”); break; case TUESDAY: System.out.println(“Today is Tuesday!”); break; case WENSDAY: System.out.println(“Today is Wensday!”); break; case THURSDAY: System.out.println(“Today is Thursday!”); break; case FRIDAY: System.out.println(“Today is Friday!”); break; default: throw new AssertionError("Unexpected value: " + this); } } }
//测试程序 for(WeekDay weekDay: EnumSet.allOf(WeekDay.class)){ System.out.println("the message is : "+weekDay.printWeekDay()); } |
现在的枚举类型Operation变得丰满多了,我们在枚举类型WeekDay中增加了一个printWeekDay方法,你也可以用WeekDay.MONDAY.printWeekDay()方法来进行信息的输出了。
枚举类型也允许定义自己的构造函数,这使得枚举常量可以初始化更多的信息。来看看我们在EnumMap与EnumSet一文中提到过的枚举类型DataBaseType,它存放了现在支持的所有数据库类型。但它仅是一个“代号”,由于和数据库相关的信息对于一个应用程序来说是固定不变的,所以把这些数据放置在枚举类型自身中更符合设计的习惯。
Java代码 |
public enum DataBaseType{
MYSQL("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/mydb"), ORACLE("oracle.jdbc.driver.OracleDriver", "jdbc:oracle:thin:@localhost:1521:sample"), DB2("com.ibm.db2.jdbc.app.DB2Driver", "jdbc:db2://localhost:5000/sample"), SQLSERVER("com.microsoft.jdbc.sqlserver.SQLServerDriver", "jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb");
private String driver;
private String url; //自定义的构造函数,它为驱动、URL赋值 DataBaseType(String driver,String url){ this.driver = driver; this.url = url; }
/** * 获得数据库驱动 * @return */ public String getDriver() { return driver; }
/** * 获得数据库连接URL * @return */ public String getUrl() { return url; } }
//测试程序 for(DataBaseType dataBaseType: EnumSet.allOf(DataBaseType.class)){ System.out.println("the driver is : "+dataBaseType.getDriver()); System.out.println("the url is : "+dataBaseType.getUrl()); } |
你注意到例子中的枚举常量是如何声明使用自定义构造函数初始化的吗?仅需要将初始化使用的数据放入在枚举常量名称后面的括号中就可以了。
现在我们设计出了两个内容丰富的枚举类型,对枚举类型的使用也变得自然了许多。你也许觉得枚举类型和类之间差别甚微。可是毕竟枚举类型有着诸多限制,你在实现自己的枚举类型时一定要遵循它们。
1. 枚举类型不能使用extends关键字,但是可以使用implements关键字。这样我们可以把不同枚举类型共有的行为提取到接口中,来规范枚举类型的行为。
2. 枚举类型的自定义构造函数并不能覆盖默认执行的构造函数,它会跟在默认构造函数之后执行。
3. 枚举类型的自定义构造函数必须是私有的。你不需要在构造函数上添加private关键字,编译器会为我们代劳的。
4. 枚举类型中枚举常量的定义必须放在最上面,其后才能是变量和方法的定义。
模板方法
谈这个话题前我们要看一下改写的printWeekDay方法,在那个例子里WeekDay是丰富一些了,不过使用switch对枚举常量逐个判断以便定制不同的行为,扩展起来要麻烦了一些。假如为WeekDay添加了一个新的枚举常量,如果你忘了同时为它在switch中添加相应的case标示,那么即使有default标示来提示错误,也只能在运行后才能发现。
怎么做能更好一点?我们前面已经认识到枚举就是一个特殊的类,它可以有方法和属性,同时每个声明的枚举项都是这个枚举类型的一个实例。那么我们能不能使用“模板方法模式”来改造一下这个枚举类呢?当然可以!我们把那个例子重构一下,变成下面这个样子:
Java代码 |
public enum WeekDay { MONDAY{ @Override public void printWeekDay() { System.out.println(“Today is Monday!”); } }, TUESDAY{ @Override public void printWeekDay() { System.out.println(“Today is Tuesday!”); } }, WENSDAY{ @Override public void printWeekDay() { System.out.println(“Today is Wensday!”); } }, THURSDAY{ @Override public void printWeekDay() { System.out.println(“Today is Thursday!”); } }, FRIDAY{ @Override public void printWeekDay() { System.out.println(“Today is Friday!”); } };
/** * 根据工作日的不同打印不同的信息 */ public abstract void printWeekDay();
} |
首先,我们把方法printWeekDay改为抽象方法,然后我们在每一个枚举常量中实现了在枚举类型里定义的这个抽象方法。这样,每为枚举类型添加一个新的枚举常量,都必须实现枚举类型中定义的抽象方法,不然编译器提示出错。之所以可以这么做的原因是,虚拟机将枚举类型中声明的每一个枚举常量,创建成为一个单独的枚举类型的子类。
这样,再配合使用Tiger里的静态导入,调用者的代码就可以这样写了:
Java代码 |
MONDAY.printWeekDay(); TUESDAY.printWeekDay(); //or better... getWeekDay().printWeekDay(); |
这些代码显然要比常见的if(weekDay == WeekDay.MONDAY){...} else if(weekDay == WeekDay.TUESDAY) else {...}形式强多了,它们易读、容易扩展和维护。
反向查找
前面说到枚举也可以自定义构造函数,可以用属性来关联更多的数据。那如果我们有这样的一种需要该怎么办呢?——我们需要根据关联的数据来得到相应的枚举项,例如下面的这种情况:
Java代码 |
public final enum Status { WAITING(0), READY(1), SKIPPED(-1), COMPLETED(5);
private int code;
private Status(int code) { this.code = code; }
public int getCode() { return code; } } |
这里每种Status对应了一个code,WAITING对应了0,而COMPLETED对应了5。如果想通过0得到WAITING这个枚举项要怎么做?
做法也很简单,使用一个静态的java.util.Map来把code和枚举项关联起来就可以了,就像这样:
Java代码 |
public final enum Status { WAITING(0), READY(1), SKIPPED(-1), COMPLETED(5);
private static final Map<Integer,Status> lookup = new HashMap<Integer,Status>();
static { for(Status s : EnumSet.allOf(Status.class)){ lookup.put(s.getCode(), s); } }
public static Status get(int code) { return lookup.get(code); }
private int code;
private Status(int code) { this.code = code; }
public int getCode() { return code; } } |
静态方法get(int)提供了需求中的反向查找能力,而静态块里使用EnumSet来把起映射做用的Map组装起来,Over!
总结:使用枚举,但不要滥用!
学习任何新版语言的一个危险就是疯狂使用新的语法结构。如果这样做,那么您的代码就会突然之间有 80% 是泛型、标注和枚举。所以,应当只在适合使用枚举的地方才使用它。那么,枚举在什么地方适用呢?一条普遍规则是,任何使用常量的地方,例如目前用 switch 代码切换常量的地方。如果只有单独一个值(例如,鞋的最大尺寸,或者笼子中能装猴子的最大数目),则还是把这个任务留给常量吧。但是,如果定义了一组值,而这些值中的任何一个都可以用于特定的数据类型,那么将枚举用在这个地方最适合不过。
发表评论
-
tomcat安装不成功.提示是:failed to install tomcat6 service ,check your setting and permis
2018-03-08 14:55 408以管理员身份运行 命令提示符,弹出窗口 ,选择“是”,输入 ... -
把系统时间设置成跟数据库的一致
2016-08-22 16:41 0public String time(int x) { ... -
struts标签<logic:iterate>的用法
2016-01-08 16:17 0<logic:iterate>主要用来 ... -
WIN7环境下cmd javac不是内部或外部命令 .
2015-07-21 11:27 1193一般步骤如下: 网上摘抄部分: JAVA_HOME ... -
jdk环境变量配置
2014-08-25 11:01 0进行java开发,首先要安装jdk,安装了jdk后还要进行环境 ... -
[转]JDBC使用TNS连接多节点Oracle
2012-06-29 15:15 1174JDBC使用TNS连接多节点O ... -
一个简单的JDBC通用工具
2012-06-29 15:01 0一个简单的JDBC通用工具 支持多种数据库,统一方式产 ... -
Java调用BCP导入数据到数据库解决标识列ID问题
2012-06-29 14:53 1087面的一篇博文讲解了调用bcp批量导出数据,对于批量导入数据则写 ... -
java 可变参数方法Object... objs
2012-06-29 14:42 4155public abstract List find(Str ... -
java调用存储过程
2012-06-14 12:34 0在java可以使用java.sql.CallableState ... -
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接 错误解决办法
2012-06-13 12:56 3044用java连接sqlserver2005时总是出现下面这个错误 ... -
javac编译外部jar包
2012-06-12 14:23 3560这个有个很简单到解决 ... -
[转]Eclipse中将Java项目(引用了第三方包) 打包为jar
2012-06-12 14:13 990如果自己的java project中需要引用额外的jar包作为 ... -
java 调用BCP导入文本数据到表
2012-06-04 15:53 0在dos下的导入语句bcp SMM_SQL_REPLICA.d ... -
[转]jdk和jre有什么区别?
2012-03-09 14:28 772来源 简单的说JDK是面 ... -
[转]Java线程:线程栈模型与线程的变量
2012-02-16 14:06 743Java线程:线程栈模型与线程的变量 SCJP5学 ... -
[转] Java线程:概念与原理
2012-02-16 13:29 795Java线程:概念与原理 ... -
Java线程:创建与启动
2012-02-16 13:26 504SCJP5学习笔记 一、定义线程 ... -
JSP页面用get传递参数乱码问题
2011-06-24 15:52 1241通过get 方式传递参数时,如果参数是中文 ,则会出现乱码现在 ... -
PO/VO/DAO/BO/POJO是什么(JAVA几种对象的解释)
2011-03-30 16:49 0/*PO:persistant object持久对 ...
相关推荐
NULL 博文链接:https://mlaaalm.iteye.com/blog/694720
java枚举小例子,简单了解枚举的用法,适合初学者使用。
java枚举结果类、根据状态值获取枚举值 Controller: /** 模块类型枚举 */ model.addAttribute("mType", ModuleTypeEnum.ModuleTypeShow()); ftl: value="${mType.key}:${mType.value}” </#list>
java 通过反射获取枚举类,及枚举类的值,枚举类枚举实例名。本项目为普通java项目
使用JDK1.6编写的枚举例子,里面有详细的注释,很有必要参考下
列举java 枚举相关信息列举java 枚举相关信息列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息 列举java 枚举相关信息
【Java面试】枚举从使用到原理
JAVA的枚举实例以及应用
java中enum枚举的详细用法。 0.0
JAVA枚举JAVA枚举
java枚举状态机
java 枚举ppt 枚举定义 用普通类模拟枚举 带构造方法的枚举 带抽象方法的枚举 单例与枚举 枚举与类集
简单总结java枚举类型,适合java初学者
Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类...
我想几乎每一个学习Java语言的人在学习枚举的时候首先的一个疑问就是“为什么不用static final字段替代?”,有这个疑问就说明你已经摸索到了枚举类型的最主要功能......
理解java枚举类型
java枚举类型的说说明,详细阐述了枚举类型的使用和注意事项
一个关于JAVA枚举类型的MHT文件,包含JAVA枚举类型的用法,以及JDK版本的问题。
java高级编程 Enum枚举 包括枚举的例子,问题 及一些文档,是复习的好资源
java enum详细教程。由浅入深,包括基本语法方面..很适合新手学习。/n各位看官。绝对超值。