前言:关于枚举类也就是enum关键字相信大家都或多或少听过,要知道的是枚举类在公司工作中用的是非常普遍的,那么关于如何使用枚举类以及枚举的实现原理到底是怎样的,请接着往下看。
1.什么是枚举
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。 是一个被命名的整型常数的集合,枚举在日常生活中很常见,例如表示星期的SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY、SATURDAY就是一个枚举。
通俗的说,枚举就是一些有序数字(从0开始)的集合,这些数字都被取了一个名字,或者说这些数字就代表着对象的序数。
2.怎么写枚举
/**
星期的枚举类
*/
public enum Weekend{
SUNDAY,
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
STARDAY;
}
3.枚举原理
枚举可以说其实就是一个普通的类,跟普通的类并不二异。我们第一次看到上面的这个枚举类
代码时可能会一脸懵,为什么大写写了几个字母然后之间用逗号隔开,这样写有锤子用啊?当时第一次接触的我也是一脸困惑。那么它到底干了什么呢,我们可以通过编译这段源代码之后,生成字节码文件反编译之后看看它到底有什么奥秘。
具体该怎么做呢?
首先在开发工具中写好这个枚举
然后我们编译好之后找生成的.class文件所在目录
如果idea的话可以在target目录下找到该文件右击选择Open IN->Explorer就能进入到Weekend.class文件位置
其次输入cmd进入控制命令台
输入javap -p Weekend.class进行反编译得到结果
我们惊喜的发现它为我们创建了一个public final class Weekend类并且继承了java.lang.Enum类
而SUNDAY这样的就是生成的一个个静态变量对象,
除此之外还有values数组以及valuesOf方法。valuesOf()方法其实都是重写了父类Enum类的方法.
最后为我们创建了一个私有的构造函数,说明枚举类是不能再通过new来创建一个实例化对象的。
其实javap这个自带的反编译程序并没有十分完整的展示这个类。这里我利用jad.exe反编译工具,真正完整的类应该是这样的。
public final class Weekend extends Enum
{
public static Weekend[] values()
{
return (Weekend[])$VALUES.clone();
}
public static Weekend valueOf(String name)
{
return (Weekend)Enum.valueOf(com/zhong/basictest/Weekend, name);
}
private Weekend(String s, int i)
{
super(s, i);
}
public static final Weekend SUNDAY;
public static final Weekend MONDAY;
public static final Weekend TUESDAY;
public static final Weekend WEDNESDAY;
public static final Weekend THURSDAY;
public static final Weekend FRIDAY;
public static final Weekend STARDAY;
private static final Weekend $VALUES[];
static
{
SUNDAY = new Weekend("SUNDAY", 0);
MONDAY = new Weekend("MONDAY", 1);
TUESDAY = new Weekend("TUESDAY", 2);
WEDNESDAY = new Weekend("WEDNESDAY", 3);
THURSDAY = new Weekend("THURSDAY", 4);
FRIDAY = new Weekend("FRIDAY", 5);
STARDAY = new Weekend("STARDAY", 6);
$VALUES = (new Weekend[] {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, STARDAY
});
}
}
看到这里相信小伙伴应该能够解开中的疑团了吧,原来每个变量名都是一个对象,再进一步了解一下Enum这个类,会发现的是我们创建每一个枚举对象的同时会把变量名和0,1这样的序数依次赋值给父类,序数是随着变量创建而增长的,也就是说父类的变量保存了我们的变量名称和序数。
我们可以用调用父类的方法name()和ordinal()取得它的名称和序数。
同样我们回到正轨,这原来就是一个普通的类嘛,于是乎我们可以可以像正常对象那样,创建有参构造(修饰符不能为public编译器会报错,目的是不让我们能实例化对象),定义变量等操作,亦或是创建方法等等。致此,枚举类也就拨云见日了,相信再遇到枚举类应该能够轻松拿下了吧,同样反编译这个手段好好利用也可以助于我们对代码的解读。
4.枚举的作用
最后,枚举类的作用有哪些呢?其实枚举类作用是简化我们创建一些不变的静态变量,可以使代码变得更加简洁,同样使用枚举类也可以避免被Class类的newInstance()方法创建对象,可以将其利用于单例模式中,保证对象的安全。