- 浏览: 403703 次
- 性别:
- 来自: 秦皇岛
最新评论
-
prayjourney:
了解了,讲的不错
DataInputStream和DataOutputStream类 -
niunianss:
将字节退回的时候,需要添加判断,最后一个字符是英文时,实际数组 ...
PushbackInputStream -
cctt_1:
不要误人子弟,那根本就不是 解释器模式!!!那是Composi ...
Interpreter(解释器)模式 -
java-大神:
[i][i]引用引用引用引用[/img][/img][/img ...
BufferedReader和BufferedWriter -
百合不是茶:
你的程序在文件输入输出流中传入agrs[0]时,会报错越界 ...
DataInputStream和DataOutputStream类
1. 在J2SE5.0中要定义枚举类型是使用enum关键词,枚举类型主要提供一些常数。如下列代码定义了Action枚举类型:
public enum Action { TURN_LEFT, TURN_RIGHT, SHOOT }
在Action.java中编写此段代码并编译,虽然语法上不像是在定义类,但枚举类型本质上就是一个类。所以编译完成后,会产生一个Action.class文件。
下面的代码是说明如何使用定义好的枚举类型一个示例:
public class EnumDemo { public static void main(String[] args) { doAction(Action.TURN_RIGHT); } public static void doAction(Action action) { switch(action) { case TURN_LEFT: System.out.println("向左转"); break; case TURN_RIGHT: System.out.println("向右转"); break; case SHOOT: System.out.println("射击"); break; } } }
运行结果:向右转。其中doAction()方法所接受的变量必须是Action枚举类型,如果对此方法输入其他类型的变量,编译器会报告错误。另外,如果在上面的switch中加入了不属于Action中枚举的值,编译器也会报告错误。例如:在上面代码case SHOOT段下面再加上以下代码:
case STOP:
System.out.println("STOP");
break;
则在编译时编译器会显示以下错误:
unqualified enumeration constant name required
case STOP:
^
2. 可以在一个独立的文件中声明枚举值,或是在某个类中声明枚举成员。例如:
public class EnumDemo2 { private enum InnerAction {TURN_LEFT,TURN_RIGHT,SHOOT}; public static void main(String[] args) { doAction(InnerAction.TURN_RIGHT); } public static void doAction(InnerAction action) { switch(action) { case TURN_LEFT: System.out.println("向左转"); break; case TURN_RIGHT: System.out.println("向右转"); break; case SHOOT: System.out.println("射击"); break; } } }
由于枚举类型本质上还是类,所以这段代码中枚举声明方式有些像在声明内嵌类。在编译完EnumDemo2.java后,会有一些额外的 .class文件产生,在此例中就是EnumDemo2$InnerAction.class与EnumDemo2$1.class。看到这两个文件,就可以知道实际上编译器产生了成员内部类和匿名内部类。
上面通过枚举类型设定常数的方式比旧版本的常数设定方式多了编译时期类型检查的好处。以下将深入讨论枚举类型的一些知识,以便深入理解。
2. 深入枚举类型:
定义枚举类型其实就是在定义一个类,只不过很多细节由编译器帮你补齐了,所以,某种程度上enum关键词的作用就像是class或interface.
当使用enum定义枚举类型时,实际上所定义出来的类型是继承自java.lang.Enum类。而每个被枚举的成员其实就是定义的枚举类型的一个实例,它们都被默认为final。无法改变常数名称所设定的值,它们也是public和static的成员,这与接口中的常量限制相同。可以通过类名称直接使用它们。
如1中所定义的枚举类型Action,TURN_LEFT,TURN_RIGHT,SHOOT都是Action的一个对象实例。因为是对象,所以,对象上自然有一些方法可以调用。如从Object继承焉的toString()方法被重新定义了,可以让你直接取得枚举值的字符串描述;values()方法可以让您取得所有的枚举成员实例,并以数组方式返回。您可以使用这两个方法来简单的将Action的枚举成员显示出来。静态valueOf()方法可以让您将指定的字符串尝试转换为枚举类型。可以用compareTo()方法来比较两个枚举对象在枚举时的顺序。-1之前,0位置相同,1之后。对于每个枚举成员,使用ordinal()方法,依枚举顺序得到位置索引,默认以0开始。
3.枚举上的方法:定义枚举类型基本上就是在定义类,定义枚举类型时也可以定义方法。如可以为枚举加上一些描述,而不是使用默认的toString()返回值来描述枚举值。如下代码所示:
public enum DetailAction { TURN_LEFT,TURN_RIGHT,SHOOT; public String getDescription() { switch(this.ordinal()) { case 0: return "向左转"; case 1: return "向右转"; case 2: return "射击"; default: return null; } } }
可以用下面的代码测试所定义的方法是否可用。
public class DetailActionDemo { public static void main(String[] args) { for(DetailAction action : DetailAction.values()) { System.out.printf("%s: %s%n",action,action.getDescription()); } } }
运行结果:
TURN_LEFT: 向左转
TURN_RIGHT: 向右转
SHOOT: 射击
4.枚举类型既然是类,那么也就可以有构造函数。只不过不得有公开(Public)的构造函数,这是为了避免直接对枚举类型实例化。如下代码:
public class DetailActioin2 { TURN_LEFT("向左转"),TURN_RIGHT("向右转"),SHOOT("射击"); private String description; //不公开的构造函数 private DetailAction2(String description) { this.description = description; } public String getDescription() { return description; } }
非公开的构造函数最常见的一个例子就是singleton模式的应用,当某个类只能有一个实例时,可由类维护唯一的实例,这时可以将构造函数设定为私有,取用此类的开发人员就不能自行新增多个实例了。Singleton模式的简易版本代码如下:
public class Singleton { //构造函数私有,只限内部调用 private SingleTon(){}; private static Singleton instance = null; public static synchronized SingleTon getInstance() { if(instance == null) instance = new Singleton(); return instance; } }
4. 因值而异的类实现(Value-Specific Class Bodies)
这个功能简单地说像是在使用匿名内部类来实现Command模式,它可以为每个枚举值定义各自的类本体与方法实现。
一种实现方式如下:
public interface IDescription { public String getDescription(); } public enum MoreAction implements IDescription { TURN_LEFT { //实现接口上的方法 public String getString() {return "向左转"} }, //注意这里的枚举值分隔使用, TURN_RIGHT { //实现接口上的方法 public String getString() {return "向右转"} }, //注意这里的枚举值分隔使用, SHOOT { //实现接口上的方法 public String getString() {return "射击"} }; //注意这里的枚举值结束使用; }
每个枚举成员的{与}之间是类本体,还可以在其中如同定义类一样地声明数据成员或者数据方法。测试这段代码的程序如下:
public class MoreActionDemo { public static void main(String[] args) { for(MoreAction action : MoreAction.values()) { System.out.printf("%s: %s%n",action,action.getDescription()); } } }
这个例子是将因值而异的类实现用在返回枚举值的描述上,可以按照相同的方式,为每个枚举值加上一些各自的方法实现,而调用的接口是统一的。执行结果如下:
D:\Java_Test>javac IDescription.java
D:\Java_Test>javac MoreAction.java
D:\Java_Test>javac MoreActionDemo.java
D:\Java_Test>java MoreActionDemo
TURN_LEFT: 向左转
TURN_RIGHT: 向右转
SHOOT: 射击
可能是利用枚举类型实现的接口中的方法,这里直接用
D:\Java_Test>javac IDescription.java 编译时会提示找不到getDescription()方法,所以,只好挨个来编译了。
也可以运用抽象方法去改写上面的MoreAction.java,如下:
public enum MoreAction2 { TURN_LEFT{ //实现抽象方法 public String getDescription() { return "向左转"; } }, //记得这里的枚举值分隔使用, TURN_RIGHT{ //实现抽象方法 public String getDescription() { return "向右转"; } }, SHOOT{ //实现抽象方法 public String getDescription() { return "射击"; } }; //记得这里的枚举值结束使用; //声明抽象方法 public abstract String getDescription(); }
然后用MoreActionDemo2.java来测试:
public class MoreActionDemo2 { public static void main(String[] args) { for(MoreAction2 action : MoreAction2.values()) { System.out.printf("%s: %s%n",action,action.getDescription()); } } }
执行结果与上面相同。
评论
哈哈*_*我也看了。。。学习了
发表评论
-
内部类总结
2009-11-27 14:28 1179一、方法及作用域内的内部类:1.在一个方法内定义的类2.在一个 ... -
finalize()方法终结条件验证 示例代码
2009-09-20 09:23 1296package Initialization; clas ... -
Proxy(代理)模式二
2009-05-15 21:16 15172. 重新思考图像代理: 现在需要思考设计模式是否 ... -
Junit简介
2009-04-08 17:46 15521. 单元测试(Unit Test) 一个单元(Un ... -
Ant简介
2009-04-08 13:10 17401. Ant可以自动完成的任务: (1)编译Java源代 ... -
专题制作--文字编辑器(文字编辑与保存)
2009-04-08 10:43 21491. 文字编辑与保存: (1). 打开文件的处理流 ... -
专题制作--文字编辑器(逻辑实现部分)
2009-04-07 22:35 18541. 事件处理: 在Java中事件以具体的对象来表 ... -
专题制作--文字编辑器(接口部分)
2009-04-07 20:28 21031. Swing入门: 若要使用J2SE来开发窗口应用 ... -
信息绑定(国际化处理)
2009-04-07 20:02 15301. 程序中的一些文字信息可以将之定义在一个属性文件中,而不定 ... -
日志(Logging)
2009-04-07 16:14 16221. 日志(Logging) 程序不免会出现错误,当 ... -
Java中的日期和时间
2009-04-07 11:26 19111. 使用Date: 使用System.cu ... -
meta-annotation
2009-04-07 09:23 30171. 所谓meta-annotation就是Annotati ... -
Annotion
2009-04-06 23:05 16361. Annotation对程序运行没有影响,它的目的在于对编 ... -
使用反射生成与操作对象(二)
2009-04-06 17:04 17231. 修改成员值: 尽管直接存取类的域成员是不被鼓励的 ... -
使用反射生成与操作对象(一)
2009-04-06 15:16 20511. 使用反射机制,可以在运行时期动态加载类并生成对象,操作对 ... -
Java中的反射(二)
2009-04-06 10:42 19801. 当在命令行模式下执行java XXX.class 指令后 ... -
Java中的反射(一)
2009-04-06 09:43 12921. Java提供的反射机制允许您在运行时动态加载类、查看类信 ... -
容器类的线程安全及ThreadLocal类
2009-04-05 21:28 30161. 容器类默认没有考虑 ... -
wait()和notify()
2009-04-05 19:06 13231. wait()、notify()、notifyAll() ... -
Java线程之同步化(Synchronized)主题
2009-04-05 16:44 26751. 如果一个对象所持有的数据可以被多线程同时共享存取,必须 ...
相关推荐
理解java枚举类型
NULL 博文链接:https://rensanning.iteye.com/blog/2013734
Java枚举类型.pdf
一个关于JAVA枚举类型的MHT文件,包含JAVA枚举类型的用法,以及JDK版本的问题。
简单总结java枚举类型,适合java初学者
java枚举类型的说说明,详细阐述了枚举类型的使用和注意事项
JAVA枚举类型的用法详解 例举了JAVA 枚举类型常见用法
java枚举结果类、根据状态值获取枚举值 Controller: /** 模块类型枚举 */ model.addAttribute("mType", ModuleTypeEnum.ModuleTypeShow()); ftl: value="${mType.key}:${mType.value}” </#list>
java枚举类型的定义使用介绍,还有示例。
JAVA枚举类型[归纳].pdf
全面掌握java枚举类型(enum-type)1
Java 枚举类型案例
近用到枚举,由于枚举变量比较多且存在一定的分组分类的关系,所以想能比较清晰的维护这些变量。今晚有空,简单研究了一下,分享出来,供大家讨论。 可供考虑的分类方式 /** * 枚举接口 * * @...
java枚举类型详细讲解,自己撰写的一本电子书,编写得很详细
2021年JAVA枚举类型知识点.docx
javaenum源代码
JAVA枚举类型的用法.doc
NULL 博文链接:https://janeky.iteye.com/blog/463611
我想几乎每一个学习Java语言的人在学习枚举的时候首先的一个疑问就是“为什么不用static final字段替代?”,有这个疑问就说明你已经摸索到了枚举类型的最主要功能......