嗨今天我们将讨论Java的一个特殊数据类型“枚举”enmulation的缩写。 它有什么特别之处让我们想象一下在一个项目中实现“月数”需要什么。 看起来没什么问题对吧我们只需要确定每个月都有哪些属性。也许我们首先需要月份的名字和月份的天数。 解决方案看起来很简单整个“shabang” 我们有一个类需要字段getter/setter和 。除非我们需要增加并实现完全的幸福:)但这里我们面临一个概念性的问题。 你可能还记得面向对象编程的主要优势之一是它可以轻松模拟现实世界的实体。一把椅子、一辆车、一颗行星——所有这些来自日常生活的概念都可以通过抽象的帮助轻松地在程序中表现。 问题在于现实世界中的一些实体的值范围非常有限。 一年只有四个季节。 一个八度里只有8个音符。 日历只有12个月。 而《十一罗汉》的丹尼·欧申只有11个朋友不过这:)无关紧要 重要的是普通的Java类无法建模这些实体并强制执行它们的自然限制。 我们这门课有所有必填字段。但如果是其他程序员使用它没人能阻止他或她创造完全疯狂的对象Enumpublic class Month { private String name; private int daysCount; public Month(String name, int daysCount) { this.name name; this.daysCount daysCount; } public String getName() { return name; } public void setName(String name) { this.name name; } public int getDaysCount() { return daysCount; } public void setDaysCount(int daysCount) { this.daysCount daysCount; } Override public String toString() { return Month{ name name \ , daysCount daysCount }; } }MonthtoString()equals()hashCode()Month编辑public class Main { Month month1 new Month(lolkek, 322); Month month2 new Month(yahoooooooooooo, 12345); }如果这出现在我们的代码里找出罪魁祸首可不容易一方面创建对象的程序员可能会意识到这个类意味着“一年中的一个月”就不会写出这些胡言乱语。 另一方面程序员只是利用了类设计师提供的技能。可以任意分配名称和天数吗这正是我们得到的。 那我们在这种情况下该怎么办说实话在 Java 1.5 发布之前程序员们不得不发挥创意:) 那时他们创造了这样的结构这里我们把月份数从十二个月缩短到三个以缩短示例。 这种设计使得问题得以解决。创建对象的能力仅限于私有构造器使用该类的程序员不能简单地创建对象。他们必须使用类开发者提供的最终静态对象。 比如这样但是Java开发者指出了现有的问题。当然程序员们能用语言中可用的工具找到解决方案固然好但看起来并不容易即使是新手也需要一个显而易见的解决方案。 于是爪哇岛也出现了。 基本上是一个提供有限对象值集的Java类。 情况如下在定义中我们表示这是一个 Java 类但这真的是真的吗是的我们甚至可以验证。 例如试着让我们的枚举继承另一个类为什么会这样 当我们写入编译器将此语句转换为以下代码正如你已经知道的Java 不支持多重继承。因此我们无法继承 。 这个新构造如何被使用它和旧的场构造有什么不同 举个例子旧的构造并不允许我们在语句中使用自己的数值集合。 想象一下我们想创建一个程序提醒我们每个月庆祝的节日正如你所见编译器在这里抛出了一个错误。 但一旦出现在 Java 1.5 中一切都变得简单得多控制台输出注意对对象的访问保持静态就像 Java 1.5 之前一样。我们不需要创建对象来访问月份。 在处理枚举时非常重要的一点是不要忘记它是一门完整的课程。 这意味着如果需要你可以在其中定义构造函数和方法。 例如在之前的代码片段中我们简单地指定了数值JANUARY FEBRUARY MARCH. 不过我们可以这样扩展我们的枚举Monthpublic class Month { private String name; private int daysCount; private Month(String name, int daysCount) { this.name name; this.daysCount daysCount; } public static Month JANUARY new Month(January, 31); public static Month FEBRUARY new Month(February, 28); public static Month MARCH new Month(March, 31); Override public String toString() { return Month{ name name \ , daysCount daysCount }; } }private Month(String name, int daysCount) { this.name name; this.daysCount daysCount; }Monthpublic class Main { public static void main(String[] args) { Month january Month.JANUARY; System.out.println(january); } }EnumEnumpublic enum Month { JANUARY, FEBRUARY, MARCH }EnumMonthpublic abstract class AbstractMonth { } // Error! The extends clause cannot be used with an enum public enum Month extends AbstractMonth { JANUARY, FEBRUARY, MARCH }public enum Monthpublic Class Month extends EnumAbstractMonthEnumstatic finalswitchpublic class HolidayReminder { public void printHolidays(Month month) { switch (month) { // Error! case JANUARY: } } }enumpublic enum Month { JANUARY, FEBRUARY, MARCH } public class HolidayReminder { public void printHolidays(Month month) { switch (month) { case JANUARY: System.out.println(New Years Day is January 1st!); break; case FEBRUARY: System.out.println(Valentines Day is February 14th!); break; case MARCH: System.out.println(Saint Patricks Day is March 17th!); break; } } } public class Main { public static void main(String[] args) { HolidayReminder reminder new HolidayReminder(); reminder.printHolidays(Month.JANUARY); } }New Years Day is January 1st!EnumMonthEnumMonthpublic enum Month { JANUARY(January, 31), FEBRUARY(February, 28), MARCH(March, 31), APRIL(April, 30), MAY(May, 31), JUNE(June, 30), JULY(July, 31), AUGUST(August, 31), SEPTEMBER(September, 30), OCTOBER(October, 31), NOVEMBER(November, 30), DECEMBER(December, 31); private String name; private int daysCount; Month(String name, int daysCount) { this.name name; this.daysCount daysCount; } public static Month[] getWinterMonths() { return new Month[]{DECEMBER, JANUARY, FEBRUARY}; } public static Month[] getSummerMonths() { return new Month[]{JUNE, JULY, AUGUST}; } public String getName() { return name; } public void setName(String name) { this.name name; } public int getDaysCount() { return daysCount; } public void setDaysCount(int daysCount) { this.daysCount daysCount; } Override public String toString() { return Month{ name name \ , daysCount daysCount }; } }编辑这里我们给出了两个字段月份名称和天数、使用这些字段的构造器、getter/setter、方法和两个静态方法。 如你所见这过程中没有任何问题。同样这确实是一个完整的课程控制台输出最后我想推荐一本非常有用的Java书即Joshua Bloch的《Effective Java》。作者是Java的创始人之一所以你可以完全信任他关于如何正确且熟练地使用语言工具的建议:) 关于我们的课程我建议你特别关注书中关于 的章节。 祝阅读愉快:)enumtoString()Enumimport java.util.Arrays; public class Main { public static void main(String[] args) { System.out.println(Arrays.toString(Month.getSummerMonths())); } }[Month{nameJune, daysCount30}, Month{nameJuly, daysCount31}, Month{nameAugust, daysCount31}]