CodeGym/Java 博客/China/Java 中的枚举类
作者
Milan Vucic
Programming Tutor at Codementor.io

Java 中的枚举类

已在 China 群组中发布
个会员
你好!在本文中,我们将介绍 Java Enums。 想象一下,你分配了以下任务:创建一个实现星期几的类。 乍一看,这似乎相当简单。你的代码如下所示:
public class DayOfWeek {

   private String title;

   public DayOfWeek(String title) {
       this.title = title;
   }

   public static void main(String[] args) {
       DayOfWeek dayOfWeek = new DayOfWeek("星期六");
       System.out.println(dayOfWeek);
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
这些代码看起来很正常,但有这样的问题:你可以将任何文本传递给 DayOfWeek 类的构造方法。这就意味着,有人可以随便创建星期几的名称,比如“青蛙”、“云彩”或“azaza322”。这显然我们不期望出现这种行为,因为一周中只有 7 天,而且每一天都有一个特定的名称。 因此,我们的任务是以某种方式限制 DayOfWeek 类的可能值范围。 在 Java 1.5 面市之前,开发人员必须独立开发自己的解决方案来解决这个问题,因为该语言没有现成的解决方案。 在那些日子里,如果程序员需要限制值的数量,则会这样做:
public class DayOfWeek {

   private String title;

   private DayOfWeek(String title) {
       this.title = title;
   }

   public static DayOfWeek SUNDAY = new DayOfWeek("星期日");
   public static DayOfWeek MONDAY = new DayOfWeek("星期一");
   public static DayOfWeek TUESDAY = new DayOfWeek("星期二");
   public static DayOfWeek WEDNESDAY = new DayOfWeek("星期三");
   public static DayOfWeek THURSDAY = new DayOfWeek("星期四");
   public static DayOfWeek FRIDAY = new DayOfWeek("星期五");
   public static DayOfWeek SATURDAY = new DayOfWeek("星期六");

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
你应该注意下面的事项:
  • 构造方法为 private。如果构造方法带有 private 修饰符,则不能用于创建对象。而且由于该类只有一个构造方法,因此无法创建任何 DayOfWeek 对象。

    public class Main {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = new DayOfWeek(); // 错误!
       		}
    }
  • 当然,该类确实具有所需数量的 public static 对象,这些对象已正确初始化(使用正确的星期几名称)。

    这允许这些对象在其他类中使用。

    public class Person {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = DayOfWeek.SUNDAY;
    
           			System.out.println(sunday);
      		 }
    }

    输出:

    DayOfWeek{title = '星期日'}
这种方法在很大程度上解决了这个问题。我们每周有 7 天可供使用,没有人可以创造新名称。Joshua Bloch 在他的《Effective Java》一书中提供了这个解决方案。顺便说一句,这本书非常受欢迎,是任何 Java 开发人员的必读之书。 随着 Java 1.5 的发布,该语言提供了针对这种情况的现成解决方案:Java Enums。Java EnumsJava 中的 Enum 也是一个类。它经过特别“微调”以解决此类问题,即创建某个有限范围的值。Java 的创建者已经有现成的示例(例如,C 已经有 enum),因此他们能够创建最好的变体。

什么是 Java Enum?

让我们回顾一下 DayOfWeek 示例:
public enum DayOfWeek {

   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
}
现在看起来简单多了:) 在内部,Enum 有 7 个静态常量。我们可以用它们来实现程序。 例如,我们编写一个程序来确定学生今天是否需要上学。学生有一个每日时间表,由 StudentSchedule 类表示:
public class StudentSchedule {

   private DayOfWeek dayOfWeek;
   // ... 其他字段


   public DayOfWeek getDayOfWeek() {
       return dayOfWeek;
   }

   public void setDayOfWeek(DayOfWeek dayOfWeek) {
       this.dayOfWeek = dayOfWeek;
   }
}
时间表对象的 dayOfWeek 变量确定今天是哪一天。 下面是学生类:
public class Student {

   private StudentSchedule schedule;
   private boolean goToSchool;

   public void wakeUp() {

       if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
           System.out.println("好哇,可以多睡会了!");
       } else {
           System.out.println("该死,又要上学了 :(");
       }
   }
}
wakeUp() 方法中,我们使用 Java Enum 来确定学生接下来应该做什么。 我们甚至没有提供有关 DayOfWeek 中每个字段的详细信息,我们也不需要:星期几该干什么那是不言自明。 如果我们就这么使用,任何开发人员都会理解代码中发生了什么。 Enum 方便使用的另一个例子是它的常量可以与 switch 语句一起使用。例如,我们编写一个严格节食的程序,其中的菜肴是按天安排的:
public class VeryStrictDiet {
   public void takeLunch(DayOfWeek dayOfWeek) {
       switch (dayOfWeek) {
           case SUNDAY:
               System.out.println("星期日晚餐!你今天甚至可以享受一点甜品。");
               break;
           case MONDAY:
               System.out.println("星期一午餐:鸡汤面!");
               break;
           case TUESDAY:
               System.out.println("星期二,今天是芹菜汤 :(");
               break;
               //... 诸如此类,直到结束
       }
   }
}
这是 Enums 与 Java 1.5 之前使用的旧解决方案相比的优势之一 — 旧解决方案不能与 switch 一起使用。你还需要了解什么Enum?Enum 是一个真正的类,我们在这方面所做的努力提供了所有可能性。 例如,如果当前星期几的实现不够充分,你可以向 DayOfWeek 添加变量、构造方法和方法:
public enum DayOfWeek {

   SUNDAY ("星期日"),
   MONDAY ("星期一"),
   TUESDAY ("星期二"),
   WEDNESDAY ("星期三"),
   THURSDAY ("星期四"),
   FRIDAY ("星期五"),
   SATURDAY ("星期六");

   private String title;

   DayOfWeek(String title) {
       this.title = title;
   }

   public String getTitle() {
       return title;
   }

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
现在,Enum 常量包含 title 字段、getter 和重写的 toString 方法。 与常规类相比, Enum 有一个严重缺陷,即不能被继承。 此外,枚举包含特征方法:
  • values():返回 Enum 中所有值的数组:

    public static void main(String[] args) {
       		System.out.println(Arrays.toString(DayOfWeek.values()));
    }

    输出:

    [DayOfWeek{title = '星期日'}, DayOfWeek{title = '星期一'}, DayOfWeek{title = '星期二'}, DayOfWeek{title = '星期三'}, DayOfWeek{title = '星期四'}, DayOfWeek{title = '星期五'}, DayOfWeek{title = '星期六'}]
  • ordinal():返回常量的序号。编号从零开始:

    public static void main(String[] args) {
    
       		int sundayIndex = DayOfWeek.SUNDAY.ordinal();
       		System.out.println(sundayIndex);
    }

    输出:

    0
  • valueOf():返回与传递的名称对应的 Enum 对象:

    public static void main(String[] args) {
       DayOfWeek sunday = DayOfWeek.valueOf("SUNDAY");
       System.out.println(sunday);
    }

    输出:

    DayOfWeek{title = '星期日'}
Java 中的枚举类 - 1注意:我们使用大写字母来指定 Enum 字段。这些是常量,因此它们使用全大写而不是 camelCase
评论
  • 受欢迎
你必须先登录才能发表评论
此页面还没有任何评论