东莞网站建设类岗位,网站流程图设计工具,北京朝阳做网站,维普网论文收录查询Java Enum原理
public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }; 实际上#xff0c;这个声明定义的类型是一个类#xff0c;它刚好有四个实例#xff0c;在此尽量不要构造新对象。
因此#xff0c;在比较两个枚举类型的值时#xff0c;永远不需要调用equals方法…Java Enum原理
public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }; 实际上这个声明定义的类型是一个类它刚好有四个实例在此尽量不要构造新对象。
因此在比较两个枚举类型的值时永远不需要调用equals方法而直接使用就可以了。(equals()方法也是直接使用, 两者是一样的效果)
Java Enum类型的语法结构尽管和java类的语法不一样应该说差别比较大。但是经过编译器编译之后产生的是一个class文件。该class文件经过反编译可以看到实际上是生成了一个类该类继承了java.lang.Enum。
例如
public enum WeekDay { Mon(Monday), Tue(Tuesday), Wed(Wednesday), Thu(Thursday), Fri( Friday), Sat(Saturday), Sun(Sunday); private final String day; private WeekDay(String day) { this.day day; } public static void printDay(int i){ switch(i){ case 1: System.out.println(WeekDay.Mon); break; case 2: System.out.println(WeekDay.Tue);break; case 3: System.out.println(WeekDay.Wed);break; case 4: System.out.println(WeekDay.Thu);break; case 5: System.out.println(WeekDay.Fri);break; case 6: System.out.println(WeekDay.Sat);break; case 7: System.out.println(WeekDay.Sun);break; default:System.out.println(wrong number!); } } public String getDay() { return day; }
}WeekDay经过反编译(javap WeekDay命令)之后得到的内容如下(去掉了汇编代码)
public final class WeekDay extends java.lang.Enum{ public static final WeekDay Mon; public static final WeekDay Tue; public static final WeekDay Wed; public static final WeekDay Thu; public static final WeekDay Fri; public static final WeekDay Sat; public static final WeekDay Sun; static {}; public static void printDay(int); public java.lang.String getDay(); public static WeekDay[] values(); public static WeekDay valueOf(java.lang.String);
}java 枚举类型enum的用法详解
为枚举添加方法 Java 为枚举类型提供了一些内置的方法同时枚举常量也可以有自己的方法。此时要注意必须在枚举实例的最后一个成员后添加分号而且必须先定义枚举实例。 例 5 下面的代码创建了一个枚举类型 WeekDay而且在该类型中添加了自定义的方法。
enum WeekDay {// 以上是枚举的成员常量必须先定义而且使用分号结束。Mon(Monday),Tue(Tuesday),Wed(Wednesday),Thu(Thursday),Fri(Friday),Sat(Saturday),Sun(Sunday);// 以上是枚举的成员变量必须于枚举成员常量后定义。private final String day; private WeekDay(String day) {this.day day;}public static void printDay(int i) {switch(i) {case 1:System.out.println(WeekDay.Mon);break;case 2:System.out.println(WeekDay.Tue);break;case 3:System.out.println(WeekDay.Wed);break;case 4:System.out.println(WeekDay.Thu);break;case 5:System.out.println(WeekDay.Fri);break;case 6:System.out.println(WeekDay.Sat);break;case 7:System.out.println(WeekDay.Sun);break;default:System.out.println(wrong number!);}}public String getDay() {return day;}
}上面代码创建了 WeekDay 枚举类型下面遍历该枚举中的所有成员并调用 printDay() 方法。示例代码如下
public static void main(String[] args) {for(WeekDay day : WeekDay.values()) {System.out.println(day day.getDay());}WeekDay.printDay(5);
}输出结果如下 MonMonday TueTuesday WedWednesday ThuThursday FriFriday SatSaturday SunSunday Fri
Java 中的 enum 还可以跟 Class 类一样覆盖基类的方法。下面示例代码创建的 Color 枚举类型覆盖了 toString() 方法。
public class Test {public enum Color {RED(红色,1),GREEN(绿色,2),WHITE(白色,3),YELLOW(黄色,4);// 成员变量private String name;private int index;// 构造方法private Color(String name,int index) {this.name name;this.index index;}// 覆盖方法Overridepublic String toString() {return this.index - this.name;}}public static void main(String[] args) {System.out.println(Color.RED.toString()); // 输出1-红色}
}EnumMap 与 EnumSet
为了更好地支持枚举类型java.util 中添加了两个新类EnumMap 和 EnumSet。使用它们可以更高效地操作枚举类型。 EnumMap 类 EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其他的 Map如 HashMap实现也能完成枚举类型实例到值的映射但是使用 EnumMap 会更加高效。
HashMap 只能接收同一枚举类型的实例作为键值并且由于枚举类型实例的数量相对固定并且有限所以 EnumMap 使用数组来存放与枚举类型对应的值使得 EnumMap 的效率非常高。 例 6 下面是使用 EnumMap 的一个代码示例。枚举类型 DataBaseType 里存放了现在支持的所有数据库类型。针对不同的数据库一些数据库相关的方法需要返回不一样的值例如示例中 getURL() 方法。 // 定义数据库类型枚举 public enum DataBaseType { MYSQUORACLE,DB2,SQLSERVER } // 某类中定义的获取数据库URL的方法以及EnumMap的声明 private EnumMapDataBaseType,Stringurls new EnumMapDataBaseType,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://sql:1433;Databasemydb”); } //根据不同的数据库类型返回对应的URL // param type DataBaseType 枚举类新实例 // return public String getURL(DataBaseType type) { return this.urls.get(type); }
在实际使用中EnumMap 对象 urls 往往是由外部负责整个应用初始化的代码来填充的。这里为了演示方便类自己做了内容填充。
从本例中可以看出使用 EnumMap 可以很方便地为枚举类型在不同的环境中绑定到不同的值上。本例子中 getURL 绑定到 URL 上在其他的代码中可能又被绑定到数据库驱动上去。 EnumSet 类 EnumSet 是枚举类型的高性能 Set 实现它要求放入它的枚举常量必须属于同一枚举类型。EnumSet 提供了许多工厂方法以便于初始化如表 2 所示。
表 2 EnumSet 类的常用方法
方法名称 描述 allOf(Class element type) 创建一个包含指定枚举类型中所有枚举成员的 EnumSet 对象 complementOf(EnumSet s) 创建一个与指定 EnumSet 对象 s 相同的枚举类型 EnumSet 对象 并包含所有 s 中未包含的枚举成员 copyOf(EnumSet s) 创建一个与指定 EnumSet 对象 s 相同的枚举类型 EnumSet 对象 并与 s 包含相同的枚举成员 noneOf(Class elementType) 创建指定枚举类型的空 EnumSet 对象 of(E first,e…rest) 创建包含指定枚举成员的 EnumSet 对象 range(E from ,E to) 创建一个 EnumSet 对象该对象包含了 from 到 to 之间的所有枚 举成员 EnumSet 作为 Set 接口实现它支持对包含的枚举常量的遍历。 for(Operation op:EnumSet.range(Operation.PLUS,Operation.MULTIPLY)) { doSomeThing(op); }
用法一常量
在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;}// 覆盖方法Overridepublic 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 class LightTest {// 1.定义枚举类型public enum Light {// 利用构造函数传参RED(1), GREEN(3), YELLOW(2);// 定义私有变量private int nCode;// 构造函数枚举类型只能为私有private Light(int _nCode) {this.nCode _nCode;}Overridepublic 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的类的类型EnumMapLight, String currEnumMap new EnumMapLight, 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() {EnumSetLight currEnumSet EnumSet.allOf(Light.class);for (Light aLightSetElement : currEnumSet) {System.out.println(当前EnumSet中数据为 aLightSetElement);}}}执行结果如下 演示枚举类型的遍历 … 当前灯nameRED 当前灯ordinal0 当前灯1 当前灯nameGREEN 当前灯ordinal1 当前灯3 当前灯nameYELLOW 当前灯ordinal2 当前灯2 演示EnmuMap对象的使用和遍历… [keyRED,value红灯] [keyGREEN,value绿灯] [keyYELLOW,value黄灯] 演示EnmuSet对象的使用和遍历… 当前EnumSet中数据为1 当前EnumSet中数据为3 当前EnumSet中数据为2 1. 所有的枚举类型都是Enum类的子类。 它们继承了这个类的许多方法。其中最有用的一个方法是toString()这个方法能够返回枚举常量名。 toString()方法的逆方法是静态方法valueOf(Class, String). 例如 Light lt (Light) Enum.valueOf(Light.class, “RED”); 将lt设置为 Light.RED。 每个枚举类型都有一个静态的values()方法它将返回一个包含全部枚举值的数组。 ordinal()方法返回enum声明中枚举常量的位置位置从0开始计数。例如 Light.GREEN.ordinal()返回1。 Enum类实现了Comparable接口 int compareTo( E other) 如果枚举常量在other之前则返回一个负值 如果thisother则返回0否则返回正值。 枚举常量的出现次序在enum 声明中给出。所以不能直接用,符号比较两个枚举值
**2. 可以创建一个enum类把它看做一个普通的类。**除了它不能继承其他类了。(java是单继承它已经继承了Enum),
可以添加其他方法覆盖它本身的方法
3. switch()参数可以使用enum了 values()方法是编译器插入到enum定义中的static方法所以当你将enum实例向上转型为父类Enum是values()就不可访问了。解决办法在Class中有一个getEnumConstants()方法所以即便Enum接口中没有values()方法我们仍然可以通过Class对象取得所有的enum实例 无法从enum继承子类如果需要扩展enum中的元素在一个接口的内部创建实现该接口的枚举以此将元素进行分组。达到将枚举元素进行分组。 使用EnumSet代替标志。enum要求其成员都是唯一的但是enum中不能删除添加元素。 EnumMap的key是enumvalue是任何其他Object对象。 enum允许程序员为eunm实例编写方法。所以可以为每个enum实例赋予各自不同的行为。 使用enum的职责链(Chain of Responsibility) .这个关系到设计模式的职责链模式。以多种不同的方法来解决一个问题。然后将他们链接在一起。当一个请求到来时遍历这个链直到链中的某个解决方案能够处理该请求。 使用enum的状态机 使用enum多路分发