- 浏览: 378048 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (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
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的。例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集”。在Java中想表示这种数据集最容易想到的写法可能是这样,我们以表示一周五天的工作日来举例: Java代码 public class WeekDay { public static final int MONDAY = 1; public static final int TUESDAY = 2; public static final int WENSDAY = 3; public static final int THURSDAY = 4; public static final int FRIDAY = 5; }
C/C++代码 |
enum weekday { MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY }; |
现在,你的类就可以使用像WeekDay.TUESDAY这样的常量了。但是这里隐藏着一些问题,这些常量是Java中int类型的常量,这意味着该方法可以接受任何int 类型的值,即使它和WeekDay中定义的所有日期都对应不上。因此,您需要检测上界和下界,在出现无效值的时候,可能还要抛出一个IllegalArgumentException。而且,如果后来又添加另外一个日期(例如WeekDay.SATURDAY ),那么必须改变所有代码中的上界,才能接受这个新值。 换句话说,在使用这类带有整型常量的类时,这个方案也许可行,但并不是非常有效。
Joshua Bloch老大这时站了出来,在他的著作《Effective Java》中提出了在这样场景下的一种非常好的模式——Type-safe enumeration pattern。这个模式简而言之就是给这样的常量类一个私有的构造方法,然后声明一些public static final 的同类型的变量暴露给使用者,例如:
Java代码 |
public class WeekDay { public static final WeekDay MONDAY = new WeekDay(1); public static final WeekDay TUESDAY = new WeekDay(2); public static final WeekDay WENSDAY = new WeekDay(3); public static final WeekDay THURSDAY = new WeekDay(4); public static final WeekDay FRIDAY = new WeekDay(5);
public int getValue(){ return value; }
private int value;
private WeekDay(int i){ this.value = i; } //other methods... } |
这样做的好处是你的程序现在接受的不是int类型的数据了,而是WeekDay的一个预定义好的static final的实例(WeekDay.TUESDAY等 ),例如: Java代码 public void setWeekDay(WeekDay weekDay){...}
而这样做也避免了可以随意向方法中传递一个不合法的int型数值(例如-1)而造成程序错误。同时,它还会带来其他的一些好处:由于这些枚举的对象都是一些类的实例,所以在里面放一些需要的属性来存放数据;又由于他们都是单例的,你可以使用equals方法或是==符号来比较它们。
Joshua Bloch大大提出的枚举模式,很好用但是好麻烦啊。如果你用过C/C++或是Pascal这样的语言的话一定会对它们的枚举类型有印象,例如在C/C++中我们可以这样定义:
然后在程序中就可以用MONDAY、TUESDAY这些变量了。这样多方便,但是Java 1.4以前的版本并没有提供枚举类型的支持,所以如果你是用JDK 1.4开发程序的话就只能像Joshua Bloch老大那样写了。从Java 5.0(代号为Tiger)开始,这种情况改变了,Java从语言层面支持了枚举类型。
枚举是Tiger的一个很重要的新特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示,它使用“enum”关键字来定义。
我们先来写一个简单的枚举类型的定义:
Java代码 |
public enum WeekDay{ MONDAY, TUESDAY, WENSDAY, THURSDAY, FRIDAY; //最后这个“;”可写可不写。 } |
这和类、接口的定义很相像嘛!Tiger中的枚举类型就是一种使用特殊语法“enum”定义的类。所有的枚举类型是java.lang.Enum的子类。这是Tiger中新引入的一个类,它本身并不是枚举类型,但它定义了所有枚举类型所共有的行为,如下表:
注意:虽然所有的枚举类型都继承自java.lang.Enum,但是你不能绕过关键字“enum”而使用直接继承Enum的方式来定义枚举类型。编译器会提示错误来阻止你这么做。
WeekDay中定义的五个枚举常量之间使用“,”分割开来。这些常量默认都是“public static final”的,所以你就不必再为它们加上“public static final”修饰(编译器会提示出错),这也是为什么枚举常量采用大写字母来命名的原因。而且每一个常量都是枚举类型WeekDay的一个实例。你可以通过类似“WeekDay.MONDAY”这种格式来获取到WeekDay中定义的枚举常量,也可以采用类似“WeekDay oneDay = WeekDay.MONDAY”的方式为枚举类型变量赋值(你不能给枚举类型变量分配除了枚举常量和null以外的值,编译器会提示出错)。
作为枚举类型实例的枚举常量是如何初始化的呢?其实答案很简单,这些枚举常量都是通过Enum中定义的构造函数进行初始化的。
Java代码 |
//java.lang.Enum中定义的构造函数, //两个参数分别是定义的枚举常量名称以及它所在的次序。 protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } |
在初始化的过程中,枚举常量的次序是按照声明的顺序安排的。第一个枚举常量的次序是0,依此累加。
枚举类型除了拥有Enum提供的方法以外,还存在着两个隐藏着的与具体枚举类型相关的静态方法——values()和valueOf(String arg0)。方法values()可以获得包含所有枚举常量的数组;方法valueOf是java.lang.Enum中方法valueOf的简化版本,你可以通过它,根据传递的名称来得到当前枚举类型中匹配的枚举常量。
我们来看一个枚举类型使用的小例子。需求中要求可以对指定的日期进行相应的信息输出。对于这么简单的需求,这里就使用枚举类型来进行处理。前面我们已经定义好了包含有五个工作日的枚举类型。下面的代码则是进行输出的方法:
Java代码 |
/** * 根据日期的不同输出相应的日期信息。 * @param weekDay 代表不同日期的枚举常量 */ public void printWeekDay(WeekDay weekDay){ switch(weekDay){ 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 hursday!”); break; System.out.println(“Today is Friday!”); break; default: } } |
在Tiger以前,switch操作仅能对int、short、char和byte进行操作。而在Tiger中,switch增加了对枚举类型的支持,因为枚举类型仅含有有限个可以使用整数代替的枚举常量,这太适合使用switch语句了!就像上面代码中那样,你在swtich表达式中放置枚举类型变量,就可以在case标示中直接使用枚举类型中的枚举常量了。
注意:case标示的写法中没有枚举类型前缀,这意味着不能将代码写成 case Operation. PLUS,只需将其写成 case PLUS即可。否则,编译器会提示出错信息。
像上面的例子一样,虽然你已经在case标示中穷尽了某个枚举类型中的所有枚举常量,但还是建议你在最后加上default标示(就像上面代码示意的那样)。因为万一为枚举类型添加一个新的枚举常量,而忘了在switch中添加相应的处理,是很难发现错误的。
为了更好的支持枚举类型,java.util中添加了两个新类:EnumMap和EnumSet。使用它们可以更高效的操作枚举类型。下面我一一介绍给你:
EnumMap是专门为枚举类型量身定做的Map实现。虽然使用其它的Map实现(如HashMap)也能完成枚举类型实例到值得映射,但是使用EnumMap会更加高效:它只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以EnumMap使用数组来存放与枚举类型对应的值。这使得EnumMap的效率非常高。
提示:EnumMap在内部使用枚举类型的ordinal()得到当前实例的声明次序,并使用这个次序维护枚举类型实例对应值在数组的位置。
下面是使用EnumMap的一个代码示例。枚举类型DataBaseType里存放了现在支持的所有数据库类型。针对不同的数据库,一些数据库相关的方法需要返回不一样的值,示例中getURL就是一个。
Java代码 |
//现支持的数据库类型枚举类型定义 public enum DataBaseType{ MYSQL,ORACLE,DB2,SQLSERVER }
//某类中定义的获取数据库URL的方法以及EnumMap的声明。 …… private EnumMap<DataBaseType ,String> urls = new EnumMap<DataBaseType ,String>(DataBaseType.class);
public DataBaseInfo(){ urls.put(DataBaseType.DB2,"jdbc:db2://localhost:5000/sample"); urls.put(DataBaseType.MYSQL,"jdbc:mysql://localhost/mydb"); urls.put(DataBaseType.ORACLE,"jdbc:oracle:thin:@localhost:1521:sample"); urls.put(DataBaseType.SQLSERVER,"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"); }
/** * 根据不同的数据库类型,返回对应的URL * @param type DataBaseType枚举类新实例 * @return */ public String getURL(DataBaseType type){ return this.urls.get(type); } |
在实际使用中,EnumMap对象urls往往是由外部负责整个应用初始化的代码来填充的。这里为了演示方便,类自己做了内容填充。
像例子中那样,使用EnumMap可以很方便的为枚举类型在不同的环境中绑定到不同的值上。如:例子中getURL绑定到URL上,在其它的代码中可能又被绑定到数据库驱动上去。
EnumSet是枚举类型的高性能Set实现。它要求放入它的枚举常量必须属于同一枚举类型。EnumSet提供了许多工厂方法以便于初始化,见下表:
EnumSet作为Set接口实现,它支持对包含的枚举常量的遍历:
Java代码 |
for(Operation op : EnumSet.range(Operation.PLUS , Operation.MULTIPLY)) { doSomeThing(op); } |
发表评论
-
tomcat安装不成功.提示是:failed to install tomcat6 service ,check your setting and permis
2018-03-08 14:55 445以管理员身份运行 命令提示符,弹出窗口 ,选择“是”,输入 ... -
把系统时间设置成跟数据库的一致
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 1233一般步骤如下: 网上摘抄部分: JAVA_HOME ... -
jdk环境变量配置
2014-08-25 11:01 0进行java开发,首先要安装jdk,安装了jdk后还要进行环境 ... -
[转]JDBC使用TNS连接多节点Oracle
2012-06-29 15:15 1223JDBC使用TNS连接多节点O ... -
一个简单的JDBC通用工具
2012-06-29 15:01 0一个简单的JDBC通用工具 支持多种数据库,统一方式产 ... -
Java调用BCP导入数据到数据库解决标识列ID问题
2012-06-29 14:53 1154面的一篇博文讲解了调用bcp批量导出数据,对于批量导入数据则写 ... -
java 可变参数方法Object... objs
2012-06-29 14:42 4233public abstract List find(Str ... -
java调用存储过程
2012-06-14 12:34 0在java可以使用java.sql.CallableState ... -
驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接 错误解决办法
2012-06-13 12:56 3200用java连接sqlserver2005时总是出现下面这个错误 ... -
javac编译外部jar包
2012-06-12 14:23 3610这个有个很简单到解决 ... -
[转]Eclipse中将Java项目(引用了第三方包) 打包为jar
2012-06-12 14:13 1036如果自己的java project中需要引用额外的jar包作为 ... -
java 调用BCP导入文本数据到表
2012-06-04 15:53 0在dos下的导入语句bcp SMM_SQL_REPLICA.d ... -
[转]jdk和jre有什么区别?
2012-03-09 14:28 814来源 简单的说JDK是面 ... -
[转]Java线程:线程栈模型与线程的变量
2012-02-16 14:06 779Java线程:线程栈模型与线程的变量 SCJP5学 ... -
[转] Java线程:概念与原理
2012-02-16 13:29 822Java线程:概念与原理 ... -
Java线程:创建与启动
2012-02-16 13:26 541SCJP5学习笔记 一、定义线程 ... -
JSP页面用get传递参数乱码问题
2011-06-24 15:52 1275通过get 方式传递参数时,如果参数是中文 ,则会出现乱码现在 ... -
PO/VO/DAO/BO/POJO是什么(JAVA几种对象的解释)
2011-03-30 16:49 0/*PO:persistant object持久对 ...
相关推荐
这篇博客将深入探讨Java枚举的特性和使用方法,包括`EnumSet`和`EnumMap`这两个与枚举相关的数据结构。 首先,枚举定义的基本语法是`public enum EnumName {constant1, constant2, ...}`。每个枚举常量都是`...
JDK5中提供了Java枚举类型的实现,与其说是一种新类型,倒不如说是一种语法糖。 public enum Season { SPRING, SUMMER, AUTUMN, WINTER } 通过反编译工具 jad来看看这段代码是如何实现的...
Java是世界上最流行的编程语言之一,尤其在企业级应用和服务器端开发中占据着主导地位。因此,对于求职者来说,掌握扎实的Java基础知识并能在面试中流利地解答相关问题至关重要。以下是一些常见的Java面试题及其详细...
2. **一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?** 一个 ".java" 源文件可以包含多个类,但只能有一个公开类(public class),且公开类的名称必须与文件名相同。其他非公开类(如 ...
1. **一个.java源文件中是否可以包括多个类(不是内部类)?有什么限制?** - 在Java中,一个源文件可以包含多个类,但最多只能有一个公共类(public class),且公共类的名称必须与文件名相同。非公共类(非public...
1. 一个 ".java" 源文件中是否可以包括多个类(不是内部类)?有什么限制? 可以有多个类,但是只能有一个 public 类,并且 public 的类名必须与文件名相一致。 2. Java 有没有 goto? Java 中有 goto 关键字,也是...
在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。...
Java规定一个源文件中可以定义多个类,但是其中只能有一个public类,并且文件名必须与这个public类的类名相同。此外,除了public类以外的所有类都必须是非public的。 2. Java有没有goto? Java语言中没有goto语句...
Java是世界上最广泛使用的编程语言之一,特别是在企业级应用和服务器端开发中占据主导地位。面试时,对于Java程序员,理解并掌握基础语法、类结构、逻辑控制以及类型系统至关重要。以下是一些Java面试中常见的问题...
Java允许在一个源文件中定义多个类,但只能有一个公共类(public class),且该公共类的名称必须与文件名相同。其他非公共类可以任意命名,但它们不作为主类使用,通常作为工具类或辅助类。 2. Java 有没有 goto? ...
在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。...
1. 一个`.java`源文件中是否可以包括多个类(不是内部类)?有什么限制? 在Java中,一个源文件可以包含多个类,但只能有一个公开类(public class),并且这个公开类的名称必须与文件名相同。其他非公开类(非...
2. **一个.java源文件中是否可以包括多个类(不是内部类)?有什么限制?** - 可以包含多个类,但只能有一个公共类(public class),文件名应与这个公共类的名称相同。 3. **Java有没有goto?** - Java中没有`...
Java是目前非常流行的一种编程语言,尤其是在企业级应用开发中。掌握Java基础知识对于求职者来说至关重要,这关系到是否能够顺利通过面试。下面将详细解释文档中提到的Java基础知识。 一、Java基础部分 1. 一个"....
1. **一个.java源文件中是否可以包括多个类(不是内部类)?有什么限制?** Java源文件可以包含多个类,但只有一个类可以是公共类(public class),其名称必须与文件名相同。其他类可以是非公共类,它们不需与...
2. **一个.java源文件中是否可以包括多个类(不是内部类)?有什么限制?** - 源文件可以包含多个类,但只能有一个公开类(public class),其余类可以是private或其他访问修饰符。非公开类无需与文件名匹配。 3. ...
2. **一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制?** 一个.java文件可以包含多个类,但只能有一个公共类(public class),且该公共类的名称必须与文件名相同。非公共类没有这个限制。 3. ...
一个 ".java" 文件中可以包含多个类,但只能有一个公共类(public class),这个公共类的名字必须与文件名相同。其他非公共类(非 public class)不受此限制,可以在同一个文件中定义。 3. **Java 有没有 goto?** ...
在Java中,语法是非常关键的一部分。包括变量声明、数据类型、运算符、控制流语句(如if-else、for、while、switch等)、异常处理(try-catch-finally结构)以及方法的定义和调用。此外,书中还会详细介绍Java的封装...
Java允许在一个源文件中定义多个类,但只有一个类可以是公共类(public),并且其名称必须与文件名相同。其他的非公共类可以在同一个文件中定义,但它们的访问级别不受此限制。 2. Java有没有goto? Java语言中没有...