JavaRush /Java 博客 /Random-ZH /Java 中的枚举:如何使用该类

Java 中的枚举:如何使用该类

已在 Random-ZH 群组中发布
你好!在这篇文章中,我将向您介绍 Java 枚举。想象一下,您被赋予了一项任务:创建一个实现星期几的类。乍一看,这并不复杂,您的代码将如下所示:
public class DayOfWeek {

   private String title;

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

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

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
一切似乎都很好,但有一个问题:您可以将任何文本传递给DayOfWeek类的构造函数。这样,某人就可以创建星期几“Frog”、“Cloud”或“azaza322”。这显然不是我们期望的行为,因为一周中只有 7 天,而且每一天都有一个名字。因此,我们的任务是以某种方式限制“星期几”类的可能值的范围。在 Java 1.5 之前,由于语言本身没有现成的解决方案,开发人员被迫自己想出一个解决方案来解决这个问题。在那些日子里,如果情况需要有限数量的值,他们会这样做:
public class DayOfWeek {

   private String title;

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

   public static DayOfWeek SUNDAY = new DayOfWeek("Sunday");
   public static DayOfWeek MONDAY = new DayOfWeek("Monday");
   public static DayOfWeek TUESDAY = new DayOfWeek("Tuesday");
   public static DayOfWeek WEDNESDAY = new DayOfWeek("Wednesday");
   public static DayOfWeek THURSDAY = new DayOfWeek("Thursday");
   public static DayOfWeek FRIDAY = new DayOfWeek("Friday");
   public static DayOfWeek SATURDAY = new DayOfWeek("Saturday");

   @Override
   public String toString() {
       return "DayOfWeek{" +
               "title='" + title + '\'' +
               '}';
   }
}
这里需要注意的是:
  • 私有构造函数。如果构造函数被标记为private修饰符,则不能使用该构造函数创建该类的对象。而且由于该类中只有一个构造函数,因此根本无法创建DayOfWeek对象。

    public class Main {
    
       		public static void main(String[] args) {
    
           			DayOfWeek sunday = new DayOfWeek();//error!
       		}
    }
  • 同时,该类包含所需数量的公共静态对象,这些对象以我们需要的方式初始化(​​日期的名称是正确的)。

    这使得在其他类中使用对象成为可能。

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

    结论:

    DayOfWeek{title='星期日'}

这种方法在很大程度上使我们能够解决问题。我们每周有 7 天可以随意支配,没有人可以创造新的。这个解决方案是由 Joshua Bloch 在《Effective Java》一书中提出的。顺便说一下,这本书非常酷,是所有 Java 开发人员的必读之作。
如何使用枚举类 - 2
随着 Java 1.5 的发布,该语言为此类情况引入了现成的解决方案 - Enum枚举。 枚举也是一个类。但它是专门为解决与我们类似的问题而“量身定制”的:创造一定范围内的有限价值。由于 Java 的创建者已经有了现成的示例(例如 C 语言,其中已经存在Enum),因此他们能够创建最佳选项。

什么是枚举?

那么,Java 中的 Enum是什么?让我们看一下同一DayOfWeek的示例:
public enum DayOfWeek {

   SUNDAY,
   MONDAY,
   TUESDAY,
   WEDNESDAY,
   THURSDAY,
   FRIDAY,
   SATURDAY
}
它看起来已经简单多了:) 在我们的Enum内部有 7 个具有静态访问的常量。我们已经可以使用它来实现程序中的逻辑了。例如,让我们编写一个程序来确定学生今天是否需要去学校。我们的学生将有自己的日常生活,由ScholarSchedule类指定:
public class ScholarSchedule {

   private DayOfWeek dayOfWeek;
   //...other fields


   public DayOfWeek getDayOfWeek() {
       return dayOfWeek;
   }

   public void setDayOfWeek(DayOfWeek dayOfWeek) {
       this.dayOfWeek = dayOfWeek;
   }
}
日模式下的dayOfWeek 变量确定今天是哪一天。这是我们学生的班级:
public class Scholar {

   private ScholarSchedule schedule;
   private boolean goToSchool;

   public void wakeUp() {

       if (this.schedule.getDayOfWeek() == DayOfWeek.SUNDAY) {
           System.out.println("Hooray, you can sleep some more!");
       } else {
           System.out.println("Damn, back to school :(");
       }
   }
}
wakeUp()方法中,我们使用枚举来确定学生的进一步操作。我们甚至没有详细描述DayOfWeek中每个变量的含义,而且这是没有必要的:星期几的机制已经很明显了,如果我们以当前的形式使用它,任何开发人员都会明白什么正在您的代码中发生。Enum便利性的另一个例子是它的常量可以与switch 语句一起使用。例如,我们正在编写一个严格饮食的程序,其中按天安排膳食:
public class VeryStrictDiet {
   public void takeLunch(DayOfWeek dayOfWeek) {
       switch (dayOfWeek) {
           case SUNDAY:
               System.out.println("Sunday lunch! Today you can even have a little sweet");
               break;
           case MONDAY:
               System.out.println("Monday Lunch: Chicken Noodles!");
               break;
           case TUESDAY:
               System.out.println("Tuesday, today is celery soup :(");
               break;
               //...and so on until the end
       }
   }
}
这是Enum 相对于 Java 1.5 之前使用的旧解决方案的 优势之一:旧解决方案无法与switch一起使用。

关于 Enum 类,您还需要了解什么?

枚举类是一个真正的类,具有它附带的所有功能。例如,如果当前的星期几的实现对您来说还不够,您可以向DayOfWeek添加变量、构造函数和方法 :
public enum DayOfWeek {

   SUNDAY ("Sunday"),
   MONDAY ("Monday"),
   TUESDAY ("Tuesday"),
   WEDNESDAY ("Wednesday"),
   THURSDAY ("Thursday"),
   FRIDAY ("Friday"),
   SATURDAY ("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有一个严重的限制——它不能被继承。此外,枚举还有其独特的方法:
  • value() :返回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='星期日'}

注意:我们将Enum元素的名称大写,因为它们是常量并且被指定为常量,而不是驼峰命名法
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION