详解 枚举
在我们之前学习数据结构与算法的时候,曾提到过一个名词 —— 枚举。
但是,在数据结构与算法的学习中,我们是这样定义枚举的:
所有可能的结果
那么,在Java中,枚举于是这么个意思
现在,右转哥就来带你深究枚举的本质:
枚举
概述:
就是一个类只能存在几个固定的对象,
那么这个就是枚举。
我们就可以使用这些对象可以表示一些固定的值。
那么,现在本人来自定义一个枚举类:
package edu.youzg.about_reflact.core; //自定义枚举类 public class Direction { String name; //定义4个该类的对象 public static final Direction front = new Direction("前"); public static final Direction behind = new Direction("后"); public static final Direction left = new Direction("左"); public static final Direction right = new Direction("右"); public static final Direction middle = new Direction(); private Direction() { } private Direction(String name) { this.name = name; } }
那么,对于上面的这种自定义枚举,对我们而言在未来工作编程中是十分麻烦的
因为我们只要想增加一个该类的对象,就要写好多重复的代码
所以,针对上述的需求,Java在JDK5之后,引入了enum关键字。
本人现在用enum关键字来实现下上面的需求:
package edu.youzg.about_reflact.core; public enum Direction { FRONT("前"), BEHIND("后"), LEFT("左"), RIGHT("右"), MIDDLE; String name; private Direction() { } private Direction(String name) { this.name = name; } }
可能有的同学注意到了本人上面的代码的一个细节 —— 构造方法是私有的!
那么,现在本人再来讲解一个enum枚举的特点:
枚举默认就是抽象的,
所以,我们没法直接去new一个枚举的对象,所以,构造方法是私有的
但是,我们可以将每一个枚举的实现类对象看作是 这样的代码的缩写:
public static final 枚举类名 枚举类对象 = new 枚举类()
正是由于是这样的代码的缩写,
所以,每一个枚举项,都是单例的
现在,本人来通过一段代码来展示下为什么本人说枚举对象是上述代码的缩写:
package edu.youzg.about_reflact.core; public enum Direction1 { //枚举默认就是抽象的 //枚举项 FRONT("前"){ @Override public void show(String name) { System.out.println(name); } }, BEHIND("后") { @Override public void show(String name) { System.out.println(name); } }, LEFT("左") { @Override public void show(String name) { System.out.println(name); } }, RIGHT("右") { @Override public void show(String name) { System.out.println(name); } }; String name; private Direction1 (String name) { //枚举中的构造方法是私有修饰的 this.name = name; } //提供抽象方法 public abstract void show(String name); }
可以看到,本人给出了一个抽象类,
所以每一个枚举对象必须要实现这个抽象方法
那么,现在,本人来讲解一下运用新型枚举类,我们要注意的问题:
- 定义枚举类要用关键字enum
- 所有枚举类都是Enum的子类,但是不能显式的写出来
- 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,
但是如果枚举类有其他的东西,这个分号就不能省略。
(建议不要省略)- 枚举类可以有构造器,但必须是private的,默认的也是private的。
- 枚举类也可以有抽象方法,但是枚举项必须重写该方法
- 枚举可以在switch语句中的使用
本人在上面提到了一个问题 :所有枚举类都是Enum的子类
所以,所有枚举类,都继承了Enum类的方法,
那么,现在本人来介绍下常用的几个API:
- int ordinal():
返回枚举项的序号- int compareTo(E o):
比较两个枚举项的 返回的是两个枚举项序号的 差值- String name():
获取枚举项的名称- String toString():
获得的字符串是 枚举项的名称- < T > T valueOf(Class< T > type,String name):
用来获取指定的枚举项
参数1:枚举类对应的字节码对象
参数2 枚举项的名称
那么,现在,本人来展示下这些API的使用:
本人先来给出一个枚举类:
package edu.youzg.about_reflact.core; public enum Direction { FRONT("前"), BEHIND("后"), LEFT("左"), RIGHT("右"); String name; private Direction() { } private Direction(String name) { this.name = name; } }
现在,本人再来给出一个测试类:
package edu.youzg.about_reflact.core; public class Test { public static void main(String[] args) { Direction front = Direction.FRONT ; Direction behind = Direction.BEHIND; Direction left = Direction.LEFT ; Direction right = Direction.RIGHT ; /* 输出每一个枚举的序号 */ System.out.println(front.ordinal()); System.out.println(behind.ordinal()); System.out.println(left.ordinal()); System.out.println(right.ordinal()); /* 通过序号进行比较 */ System.out.println("----------------------------------"); System.out.println(front.compareTo(right)); System.out.println("----------------------------------"); System.out.println(front.name()); System.out.println("----------------------------------"); System.out.println(front.toString()); System.out.println(front); /* 获取指定的枚举项 */ System.out.println("----------------------------------"); // <T> T valueOf(Class<T> type,String name): 用来获取指定的枚举项 // type: 表示的是对应的枚举的字节码文件对象 // name: 就是枚举项的名称 Direction direction = Direction.valueOf(Direction.class, "RIGHT") ; System.out.println(direction); /* 获取该枚举类的所有枚举项 */ System.out.println("----------------------------------"); Direction[] directions = Direction.values() ; for(Direction d : directions){ System.out.println(d); } } }
现在,本人来展示下运行结果: