除了上一篇中的同步相关的知识之外,还有一个知识点——枚举enum,也同样重要。
简单介绍一下枚举类型吧:
枚举是在j5中新出的一种类型,它是一种很特殊的数据类型,我们可以把它看成一种特殊的类。因为它与类相比,多了一些约束,而又比类简洁。
枚举使用
相信枚举的使用大家都不会太陌生,但这里还是写一个简单的例子吧:
public class EnumText { public static void main(String[] args) { // TODO Auto-generated method stub Day day = Day.MONDAY; System.out.println(day); } } enum Day{ MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNNDAY }
下面的Day为我们定义的枚举类型,里面的一共有7个枚举常量分别是MONDAY.........SUNNDAY。
我们在main中创建了一个Day类型,制定为Day中的MONDAY枚举常量,然后sysout打印出来。
结果如下:
MONDAY
这个可以说是枚举里面最简单的使用了,在枚举类型没有产生之前,我们可以通过静态常量的方式实现上述的方法:
class NotEnum { public static final int MONDAY = 0; public static final int TUESDAY = 1; public static final int WEDNESDAY = 2; public static final int THURSDAY = 3; public static final int FRIDAY = 4; public static final int SATURDAY = 5; public static final int SUNNDAY = 6; }
比如我们想要实现一个switch判断功能,那么在没有枚举的情况,可以用上述方法实现。当然用枚举可以实现,而且这么一对比,我们发现枚举的方法貌似更简单吧。
实现原理
现在我们注意上面中的一行代码:
Day day = Day.MONDAY;
我们知道在java中只有类或接口是这种方式声明,我们定义Day是一个枚举类型,它也可以这样声明,是不是说明有一个Day类呢?我们来验证一下:
jibaideMacBook-Pro:Desktop jibai$ ls EnumText.java jibaideMacBook-Pro:Desktop jibai$ javac EnumText.java jibaideMacBook-Pro:Desktop jibai$ ls Day.class EnumText.class EnumText.java jibaideMacBook-Pro:Desktop jibai$
首先打开命令工具,我们先看一下当前目录下的java文件只有EnumText一个。
接着通过javac编译,我们发现在编译过后除了EnumText.class文件之外,还有一个Day.class文件。这是不是验证了我们之前说过的,可以将Day看做是一个类。
实现原理:我们在使用enum创建了枚举类型,在经过编译之后,会将其转换为一个实实在在的类,该类继承自java.lang.Enum类,且:
- 类中已经为每个枚举常量创建对应的实例对象。
- 在类中创建了两个方法:valuesOf和values。
//反编译Day.class final class Day extends Enum { //编译器为我们添加的静态的values()方法 public static Day[] values() { return (Day[])$VALUES.clone(); } //编译器为我们添加的静态的valueOf()方法,注意间接调用了Enum也类的valueOf方法 public static Day valueOf(String s) { return (Day)Enum.valueOf(com/zejian/enumdemo/Day, s); } //私有构造函数 private Day(String s, int i) { super(s, i); } //前面定义的7种枚举实例 public static final Day MONDAY; public static final Day TUESDAY; public static final Day WEDNESDAY; public static final Day THURSDAY; public static final Day FRIDAY; public static final Day SATURDAY; public static final Day SUNDAY; private static final Day $VALUES[]; static { //实例化枚举实例 MONDAY = new Day("MONDAY", 0); TUESDAY = new Day("TUESDAY", 1); WEDNESDAY = new Day("WEDNESDAY", 2); THURSDAY = new Day("THURSDAY", 3); FRIDAY = new Day("FRIDAY", 4); SATURDAY = new Day("SATURDAY", 5); SUNDAY = new Day("SUNDAY", 6); $VALUES = (new Day[] { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }); } }
我们把这段反编译的代码分为三部分:从上而下分别是:
- 创建的两个方法values和valueOf
- 私有化构造方法
- 实例创建并在static代码块中初始化。
关于前面两部分等会儿再说,我们先看第三部分:
我们在Day中为每个Day的枚举常量都创建了对应的Day引用,并在static代码块中初始化(static代码块中的代码在类加载阶段完成,所以该过程只会进行一次)。
接着我们创建了两个方法,我们来看一下他们是干什么的:
valueOf是返回对应枚举常量名的Day对象,values是返回所有枚举常量对应的Day对象的数组。
Enum常见方法
上面说到在编译之后生成的Day类是继承自Enum类的,我们来看一下这个类的一些主要方法:
String name(); | 返回枚举常量的名称 |
String toString(); | 同上 |
Class<?> getDeclaringCLass() | 返回枚举常量对应的类的class对象 |
int ordinal(); | 返回枚举常量的序数(序数按照声明位置,从0开始) |
int compareTo(E o); | 与o比较顺序:为负表示小于,0表示相等,为正表示大于 |
<T extends Enum<T>> T valueOf(Class<T> enumType ,String name ) |
返回指定名称(name)的枚举常量。 enumType参数表示对应的哪个类 |
枚举的更多使用
现在我们知道枚举类型经过编译后会产生一个类类型,而且在枚举内的枚举常量都对应一个类的实例。还有两个方法valueOf和values分别用来根据枚举常量名来获取对应的类和获取全部的类的数组。
我们还可以在枚举类型里面添加方法和属性,反正最后编译完了都是类-。+:
public class EnumText { public static void main(String[] args) { // TODO Auto-generated method stub Day day = Day.MONDAY; System.out.println(day); day.sysoutTag(); } } enum Day{ MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNNDAY; private String TAG = "tag"; public void asd() { System.out.println("我是asd"); } public void sysoutTag() { System.out.println(TAG); } }在Day中我们添加了一个字符串tag和两个方法(), 注意一定要将枚举常量写在最上面。
让枚举类实现接口
由于枚举对应的类要继承java.lang,Enum类,所以无法继承其他类,但是可以实现接口。
interface Weather{ boolean isSunny(); } enum Day implements Weather{ MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNNDAY; private String TAG = "tag"; public void asd() { System.out.println("我是asd"); } public void sysoutTag() { System.out.println(TAG); } @Override public boolean isSunny() { // TODO Auto-generated method stub return false; } }
这只是枚举的一小部分知识,由于笔者不是深入研究这个的,所以只说了一些会用到的知识点。
希望大家多多支持!!!