java6枚举类型
java.lang.Enum > 使用enum定义。
类如:
public class EnumDemo {
enum Edge {
TOP, BOTTOM, LEFT, RIGHT//定义了一个enum类型的实例,一个枚举类型除了那些由枚举常量定义的实例外没有任何其他实例。
};
public static void main(String arg[]) {
Edge edge1 = Edge.LEFT;
Edge edge2 = Edge.LEFT;
//由于每个枚举类型的实例在一个程序中只能有一个,所以我们可以使用==来判断是否相同。
System.out.println("Can we use == to judge equals:"+ (edge1 == edge2));
int i = edge1.ordinal();
System.out.println("The value of i: " + i);
System.out.println(edge1);
String str = "";
switch(edge1) {
/* case Edge.TOP: This is wrong*/
case TOP: str = "The top edge"; break;
case BOTTOM: str = "The bottom edge"; break;
case LEFT: str = "The left edge"; break;
case RIGHT: str = "The right edge"; break;
}
System.out.println(str);
}
这就解决了switch不能对字符串进行的缺点了。注意:枚举类型也是类,里面的成员实际上是静态的final类型的枚举类型实例。
为了更好的理解枚举类型,我们用普通类模拟一下该枚举类 :
public abstract class WeekDay {
private int workhours;
private boolean work;
private WeekDay(int workhours, boolean work) {
this.workhours = workhours;
this.work = work;
}
protected abstract WeekDay getNextDay();
public static final WeekDay MONDAY = new WeekDay(8,true){
public WeekDay getNextDay() {
return TUESDAY;
}
@Override
public String toString() {
return "MONDAY";
}
};
public static final WeekDay TUESDAY = new WeekDay(8,true){
public WeekDay getNextDay() {
return WEDNESDAY;
}
@Override
public String toString() {
return "TUESDAY";
}
};
public static final WeekDay WEDNESDAY = new WeekDay(8,true){
public WeekDay getNextDay() {
return THURSDAY;
}
@Override
public String toString() {
return "WEDNESDAY";
}
};
public static final WeekDay THURSDAY = new WeekDay(8,true){
public WeekDay getNextDay() {
return FRIDAY;
}
@Override
public String toString() {
return "THURSDAY";
}
};
public static final WeekDay FRIDAY = new WeekDay(8,true){
public WeekDay getNextDay() {
return SATURDAY;
}
@Override
public String toString() {
return "FRIDAY";
}
};
public static final WeekDay SATURDAY = new WeekDay(4,true){
public WeekDay getNextDay() {
return SUNDAY;
}
@Override
public String toString() {
return "SATURDAY";
}
};
public static final WeekDay SUNDAY = new WeekDay(0,false){
public WeekDay getNextDay() {
return MONDAY;
}
@Override
public String toString() {
return "SUNDAY";
}
};
private static void showDay(WeekDay d) {
if(d.isWeekday()) {
System.out.println(d + " is a weekday and has " +
d.getHours() + " working hours.");
} else {
System.out.println(d + " is not a weekday and has " +
d.getHours() + " working hours.");
}
}
private int getHours() {
// TODO Auto-generated method stub
return workhours;
}
private boolean isWeekday() {
return work;
}
public static void main(String[] args) {
WeekDay day = WeekDay.FRIDAY;
showDay(day);
day = WeekDay.FRIDAY.getNextDay();
showDay(day);
day = day.getNextDay();
showDay(day);
}
}
因此,有以下更复杂的应用:
public enum Day {
MONDAY (8,true){//首先使用了子类继承的匿名类方式进行了对父类构造函数的,并且在子类中完成了父类的抽象方法
public Day getNextDay() {
return TUESDAY;
}
},
TUESDAY (8,true){
public Day getNextDay() {
return WEDNESDAY;
}
},
WEDNESDAY (8,true){
public Day getNextDay() {
return THURSDAY;
}
},
THURSDAY (8,true){
public Day getNextDay() {
return FRIDAY;
}
},
FRIDAY (8,true){
public Day getNextDay() {
return SATURDAY;
}
},
SATURDAY (4,false){
public Day getNextDay() {
return SUNDAY;
}
},
SUNDAY (0,false){
public Day getNextDay() {
return MONDAY;
}
};
private int hours;
private boolean weekday;
Day(int workHours,boolean weekdayFlag) {
hours = workHours;
weekday = weekdayFlag;
}
private abstract Day getNextDay();
public int getHours() {
return(hours);
}
public boolean isWeekday() {
return(weekday);
}
private static void showDay(Day d) {
if(d.isWeekday()) {
System.out.println(d + " is a weekday and has " +
d.getHours() + " working hours.");
} else {
System.out.println(d + " is not a weekday and has " +
d.getHours() + " working hours.");
}
}
public static void main(String arg[]) {
Day day;
day = Day.TUESDAY;
showDay(day);
day = Day.SATURDAY;
showDay(day);
day = Day.THURSDAY.getNextDay();
showDay(day);
}
}
注意:
1.注意枚举类型不能定义为abstract或者final。
2.枚举类中定义了抽象方法,但是枚举类却没有实例去实现这个抽象方法,这样会报错。
3.一个枚举类型除非包含至少一个枚举常量带有class body,否则就是隐式final的。
4.嵌套 (在一个类中定义的枚举)的枚举类型是隐式static的,若显示赋予就会出错。
5.EnumSet包含了许多静态方法用来指定不同的集合建立和读取方式。
常用用法:
用法一:常量
在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
public enum Color {
RED, GREEN, BLANK, YELLOW
}
用法二:switch
JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Signal {
GREEN, YELLOW, RED
} public class TrafficLight {
Signal color = Signal.RED; public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
用法三:向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index; // 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
} // 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
} // get set 方法
public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getIndex() {
return index;
} public void setIndex(int index) {
this.index = index;
}
}
用法四:覆盖枚举的方法
下面给出一个toString()方法覆盖的例子。
public class Test {
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index; // 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
} // 覆盖方法
@Override
public String toString() {
return this.index + "_" + this.name;
}
} public static void main(String[] args) {
System.out.println(Color.RED.toString());
}
}
用法五:实现接口
所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
public interface Behaviour {
void print(); String getInfo();
} public enum Color implements Behaviour {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index; // 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
} // 接口方法 @Override
public String getInfo() {
return this.name;
} // 接口方法
@Override
public void print() {
System.out.println(this.index + ":" + this.name);
}
}
用法六:使用接口组织枚举
public interface Food {
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO
} enum Dessert implements Food {
FRUIT, CAKE, GELATO
}
}
用法七:关于枚举集合的使用
java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档
枚举和常量定义的区别
一、 通常定义常量方法
我们通常利用public final static方法定义的代码如下,分别用1表示红灯,3表示绿灯,2表示黄灯。
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); } }
三、 完整示例代码
枚举类型的完整演示代码如下:
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
四、 通常定义常量方法和枚举定义常量方法区别
以下内容可能有些无聊,但绝对值得一窥
1. 代码:
public class State { public static final int ON = 1; public static final Int OFF= 0; }
有什么不好了,大家都这样用了很长时间了,没什么问题啊。
首先,它不是类型安全的。你必须确保是int
其次,你还要确保它的范围是0和1
最后,很多时候你打印出来的时候,你只看到 1 和0 ,
但其没有看到代码的人并不知道你的企图,抛弃你所有旧的public static final常量
2. 可以创建一个enum类,把它看做一个普通的类。除了它不能继承其他类了。(java是单继承,它已经继承了Enum),
可以添加其他方法,覆盖它本身的方法
3. switch()参数可以使用enum了
4. values()方法是编译器插入到enum定义中的static方法,所以,当你将enum实例向上转型为父类Enum是,values()就不可访问了。解决办法:在Class中有一个getEnumConstants()方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有的enum实例
5. 无法从enum继承子类,如果需要扩展enum中的元素,在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组。达到将枚举元素进行分组。
6. 使用EnumSet代替标志。enum要求其成员都是唯一的,但是enum中不能删除添加元素。
7. EnumMap的key是enum,value是任何其他Object对象。
8. enum允许程序员为eunm实例编写方法。所以可以为每个enum实例赋予各自不同的行为。
9. 使用enum的职责链(Chain of Responsibility) .这个关系到设计模式的职责链模式。以多种不同的方法来解决一个问题。然后将他们链接在一起。当一个请求到来时,遍历这个链,直到链中的某个解决方案能够处理该请求。
10. 使用enum的状态机
11. 使用enum多路分发
java6枚举类型的更多相关文章
- Asp.Net 将枚举类型(enum)绑定到ListControl(DropDownList)控件
在开发过程中一些状态的表示使用到枚举类型,那么如何将枚举类型直接绑定到ListControl(DropDownList)是本次的主题,废话不多说了,直接代码: 首先看工具类代码: /// <su ...
- golang枚举类型 - iota用法拾遗
在c#.java等高级语言中,经常会用到枚举类型来表示状态等.在golang中并没有枚举类型,如何实现枚举呢?首先从枚举的概念入手. 1.枚举类型定义 从百度百科查询解释如下:http://baike ...
- 第三条:用私有构造器或者枚举类型强化Singleton属性
1.使用单元素的枚举类型 public enum Singleton implements Serializable { INSTANCE; private String field; public ...
- 在WPF中使用变通方法实现枚举类型的XAML绑定
问题缘起 WPF的分层结构为编程带来了极大便利,XAML绑定是其最主要的特征.在使用绑定的过程中,大家都普遍的发现枚举成员的绑定是个问题.一般来说,枚举绑定多出现于与ComboBox配合的情况,此时我 ...
- 窥探Swift之别样的枚举类型
想必写过程序的童鞋对枚举类型并不陌生吧,使用枚举类型的好处是多多的,在这儿就不做过多的赘述了.Fundation框架和UIKit中的枚举更是数不胜数,枚举可以使你的代码更易阅读并且可以提高可维护性.在 ...
- C#枚举类型的常用操作总结
枚举类型是定义了一组"符号名称/值"配对.枚举类型是强类型的.每个枚举类型都是从system.Enum派生,又从system.ValueType派生,而system.ValueTy ...
- TypeScript中的枚举类型
TypeScript拓展了Javascript原生的标准数据类型集,增加了枚举类型(enmu)和其他语言一 样 它提供我们一种数字类型的值,用来设置由于辨别的名字和方法 enum Students { ...
- Python 中的枚举类型~转
Python 中的枚举类型 摘要: 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表 ...
- java 枚举类型 构造函数及用法
// 1. 定义枚举类型 public enum Light { // 利用构造函数传参 RED (1), GREEN (3), YELLOW (2); // 定义私有变量 private int n ...
随机推荐
- 进程与网络监控和ssh简单使用
进程的概念和管理 进程: 正在执行的程序 线程: 轻量级的进程 进程有独立的地址空间,线程没有 线程不能独立存在,它是由进程创建.Thread1.在linux中,每个执行的程序都称为一个进程.每一个进 ...
- 使用VisualStudio读写NI FPGA板卡实例(基于FPGA Interface C API Generator)
实验平台说明:安装了NI LabVIEW 2015 32bit版本,安装了NI FPGA Interface C API Generator,安装了硬件PCIe-7842R:安装了Visual Stu ...
- PentesterLab-From SQL Injection to Shell: PostgreSQL edition
一.打开页面,随便点了几下,返现和From SQL Injection to Shell差不多,直奔主题开始注入 由于PostgreSQL与MySQL不同,几个关注点需要注意下 二.order by下 ...
- -Linux下的虚拟机安装与管理
一.虚拟机安装 首先安转之前,要提前下载一个镜像,这里是:rhel-server-7.0-x86_64-dvd.iso 1)图形化方法 [1]在本机打开终端,切换到超级用户下.输入命令:virt-ma ...
- Linux输入输出管理
一.系统输入输出的理解 运行一个程序时,需要从某个位置读取输入信息,然后CPU处理,最后将输出 显示在屏幕或文件中:其中,某个位置相当于输入设备,屏幕或文件为输出设备. 标准输入:stdin,默认 ...
- Kotlin Reference (五) Packages
most from reference 包 源文件可以从包声明开始: package foo.bar fun baz() {} class Goo {} // ... 源文件的所有内容(如类和函数)都 ...
- 创建Azure Function
azure function的用途在于运行一些逻辑简单的执行逻辑,比如batch job,定时任务,webhook等等.1. 创建azure function创建完毕后,进入app service,选 ...
- IOS开发 警告 All interface orientations must be supported unless the app requires full screen.
在IOS开发中遇到警告 All interface orientations must be supported unless the app requires full screen. 只要勾上R ...
- Swift GCD
var queue: dispatch_queue_t = dispatch_get_main_queue()// 主线程 queue = dispatch_get_global_queue(DISP ...
- BloomFilter ——大规模数据处理利器
BloomFilter——大规模数据处理利器 Bloom Filter是由Bloom在1970年提出的一种多哈希函数映射的快速查找算法.通常应用在一些需要快速判断某个元素是否属于集合,但是并不严格要求 ...