[关闭]
@tsing1226 2016-10-13T19:57:11.000000Z 字数 4294 阅读 915

java

Java 语言中 Enum 类型的使用介绍


如何定义Enum类型

用 enum 关键字加上名称和大括号包含起来的枚举值体。比如:

  1. enum RainbowColor {RED,ORANGE,YELLOW,GREEN,CYAN,BLUE,PURPLE}

引入枚举类型最大的好处就是扩大switch语句使用范围。

  1. //定义一周七天的枚举类型
  2. public enum WeekDayEnum {Mon,Tue,Wed,Thu,Fri,Sat,Sun}
  3. // 读取当天的信息
  4. WeekDayEnum today = readToday();
  5. // 根据日期来选择进行活动
  6. switch(today) {
  7. Mon: do something;
  8. break;
  9. Tue: do something;
  10. break;
  11. Wed: do something;
  12. break;
  13. Thu: do something;
  14. break;
  15. Fri: do something;
  16. break;
  17. Sat: play sports game;
  18. break;
  19. Sun: have a rest;
  20. break;
  21. }

如何定制Enum类型

  1. // 定义 RSS(Really Simple Syndication) 种子的枚举类型
  2. public enum NewsRSSFeedEnum {
  3. // 雅虎头条新闻 RSS 种子
  4. YAHOO_TOP_STORIES("http://rss.news.yahoo.com/rss/topstories"),
  5. //CBS 头条新闻 RSS 种子
  6. CBS_TOP_STORIES("http://feeds.cbsnews.com/CBSNewsMain?format=xml"),
  7. // 洛杉矶时报头条新闻 RSS 种子
  8. LATIMES_TOP_STORIES("http://feeds.latimes.com/latimes/news?format=xml");
  9. // 枚举对象的 RSS 地址的属性
  10. private String rss_url;
  11. // 枚举对象构造函数
  12. private NewsRSSFeedEnum(String rss) {
  13. this.rss_url = rss;
  14. }
  15. // 枚举对象获取 RSS 地址的方法
  16. public String getRssURL() {
  17. return this.rss_url;
  18. }
  19. }

使用时主要事项:

  1. enum 类型不支持 public 和 protected 修饰符的构造方法,因此构造函数一定要是 private 或 friendly 的。也正因为如此,所以枚举对象是无法在程序中通过直接调用其构造方法来初始化的。
  2. 定义 enum 类型时候,如果是简单类型,那么最后一个枚举值后不用跟任何一个符号;但如果有定制方法,那么最后一个枚举值与后面代码要用分号';'隔开,不能用逗号或空格。
  3. 由于 enum 类型的值实际上是通过运行期构造出对象来表示的,所以在 cluster 环境下,每个虚拟机都会构造出一个同义的枚举对象。因而在做比较操作时候就需要注意,如果直接通过使用等号 ( ‘ == ’ ) 操作符,这些看似一样的枚举值一定不相等,因为这不是同一个对象实例

  1. // 定义一个一周七天的枚举类型
  2. package example.enumeration.codes;
  3. public enum WeekDayEnum {
  4. Mon(1), Tue(2), Wed(3), Thu(4), Fri(5), Sat(6), Sun(7);
  5. private int index;
  6. WeekDayEnum(int idx) {
  7. this.index = idx;
  8. }
  9. public int getIndex() {
  10. return index;
  11. }
  12. }
  13. // 客户端程序,将一个枚举值通过网络传递给服务器端
  14. package example.enumeration.codes;
  15. import java.io.IOException;
  16. import java.io.ObjectOutputStream;
  17. import java.io.OutputStream;
  18. import java.net.InetSocketAddress;
  19. import java.net.Socket;
  20. import java.net.UnknownHostException;
  21. public class EnumerationClient {
  22. public static void main(String... args) throws UnknownHostException, IOException {
  23. Socket socket = new Socket();
  24. // 建立到服务器端的连接
  25. socket.connect(new InetSocketAddress("127.0.0.1", 8999));
  26. // 从连接中得到输出流
  27. OutputStream os = socket.getOutputStream();
  28. ObjectOutputStream oos = new ObjectOutputStream(os);
  29. // 将星期五这个枚举值传递给服务器端
  30. oos.writeObject(WeekDayEnum.Fri);
  31. oos.close();
  32. os.close();
  33. socket.close();
  34. }
  35. }
  36. // 服务器端程序,将从客户端收到的枚举值应用到逻辑处理中
  37. package example.enumeration.codes;
  38. import java.io.*;
  39. import java.net.ServerSocket;
  40. import java.net.Socket;
  41. public class EnumerationServer {
  42. public static void main(String... args) throws IOException, ClassNotFoundException {
  43. ServerSocket server = new ServerSocket(8999);
  44. // 建立服务器端的网络连接侦听
  45. Socket socket = server.accept();
  46. // 从连接中获取输入流
  47. InputStream is = socket.getInputStream();
  48. ObjectInputStream ois = new ObjectInputStream(is);
  49. // 读出客户端传递来的枚举值
  50. WeekDayEnum day = (WeekDayEnum) ois.readObject();
  51. // 用值比较方式来对比枚举对象
  52. if (day == WeekDayEnum.Fri) {
  53. System.out.println("client Friday enum value is same as server's");
  54. } else if (day.equals(WeekDayEnum.Fri)) {
  55. System.out.println("client Friday enum value is equal to server's");
  56. } else {
  57. System.out.println("client Friday enum value is not same as server's");
  58. }
  59. // 用 switch 方式来比较枚举对象
  60. switch (day) {
  61. case Mon:
  62. System.out.println("Do Monday work");
  63. break;
  64. case Tue:
  65. System.out.println("Do Tuesday work");
  66. break;
  67. case Wed:
  68. System.out.println("Do Wednesday work");
  69. break;
  70. case Thu:
  71. System.out.println("Do Thursday work");
  72. break;
  73. case Fri:
  74. System.out.println("Do Friday work");
  75. break;
  76. case Sat:
  77. System.out.println("Do Saturday work");
  78. break;
  79. case Sun:
  80. System.out.println("Do Sunday work");
  81. break;
  82. default:
  83. System.out.println("I don't know which is day");
  84. break;
  85. }
  86. ois.close();
  87. is.close();
  88. socket.close();
  89. }
  90. }

Enum 相关工具类

两个工具类两个工具类:EnumSet 和 EnumMap

  1. enum WeekDayEnum { Mon, Tue, Wed, Thu, Fri, Sat, Sun }

你能够在每周七天日期中进行迭代,EnumSet 类提供一个静态方法 range 让迭代很容易完成

  1. for(WeekDayEnum day : EnumSet.range(WeekDayEnum.Mon, WeekDayEnum.Fri)) {
  2. System.out.println(day);
  3. }

输出结果:

  1. Mon
  2. Tue
  3. Wed
  4. Thu
  5. Fri

EnumSet 还提供了很多个类型安全的获取子集的 of 方法,使你很容易取得子集

  1. EnumSet<WeekDayEnum> subset = EnumSet.of(WeekDayEnum.Mon, WeekDayEnum.Wed);
  2. for (WeekDayEnum day : subset) {
  3. System.out.println(day);
  4. }

输出结果:

  1. Mon
  2. Wed

与 EnumSet 类似,EnumMap 也是一个高性能的 Map 接口实现,用来管理使用枚举类型作为 keys 的映射表,内部是通过数组方式来实现。EnumMap 将丰富的和安全的 Map 接口与数组快速访问结合到一起,如果你希望要将一个枚举类型映射到一个值,你应该使用 EnumMap。看下面的例子:

  1. // 定义一个 EnumMap 对象,映射表主键是日期枚举类型,值是颜色枚举类型
  2. private static Map<WeekDayEnum, RainbowColor> schema =
  3. new EnumMap<WeekDayEnum, RainbowColor>(WeekDayEnum.class);
  4. static{
  5. // 将一周的每一天与彩虹的某一种色彩映射起来
  6. for (int i = 0; i < WeekDayEnum.values().length; i++) {
  7. schema.put(WeekDayEnum.values()[i], RainbowColor.values()[i]);
  8. }
  9. }
  10. System.out.println("What is the lucky color today?");
  11. System.out.println("It's " + schema.get(WeekDayEnum.Sat));

输出结果:

  1. What is the lucky color today?
  2. It's BLUE

参考文献

http://www.ibm.com/developerworks/cn/java/j-lo-enum/

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注