1、 enum关键字(java 5+)可以将一组具名的值得有限集合创建为 一种新的类型,而这些具名的值可以供常规的程序组件使用。按照命名规范,枚举实例一般为大写字母表示,若存在多个单词,则用"_"分隔,如:ORDER_STATUS;Enum提供了hashCode()和equals()方法,可以用==判断enum实例是否相等,同时也实现了Comparable接口,具备compareTo()方法;显然,enum不支持继承,可以实现
1.1 values()
使用values()方法遍历enum,返回enum实例数组,其数组元素顺序与enum中声明顺序一致。所有自定义的enum均隐式的继承自超类Enum,查看Enum类发现其中并没有定义values()方法,这其实是编译器添加的static修饰的方法,如下
public enum InitEnum {
YES,NO,OK;
}
public static void main(String[] args) {
Class clazz = InitEnum.class;
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
}
//***output***
values
valueOf
由于values()方法是static的,所有当自定义的enum向上转出Enum时,values()方法即不可用,此时如何获取enum的值呢?如下,可通过getEnumConstants()方法获取
public enum InitEnum {
YES, NO, OK;
}
public static void main(String[] args) {
Enum yes = InitEnum.YES;
// yes.values(); TODO no such method
for (Enum en : yes.getClass().getEnumConstants()) {
System.out.println(en);
}
}
//***output***
YES,NO,OK
1.2 ordinal()
ordinal()方法返回enum实例在声明时的次序,从0开始
public enum InitEnum {
YES, NO, OK;
}
public static void main(String[] args) {
int ordinal = InitEnum.YES.ordinal();
System.out.println(ordinal);
}
//***output***
0
1.3 name()
name()方法用于返回enum声明的实例名称,若不存在则会抛出异常
String name = InitEnum.YES.name();
1.4 enum中定义方法
enum在大部分时候均类似于实体类,故在enum中也可自定义方法,甚至是main方法,但是需要注意几点:
1>声明enum实例的最后必须添加一个分号
2>声明enum实例代码部分必须放置在自定义方法前面(上面),否则编译会出错
public enum InitEnum {
YES, NO, OK; // 注意分号;实例声明顺序先于方法
public void customize(){
// TODO ……
}
public static void main(String[] args) {
// TODO ……
}
}
1.5 enum覆盖方法
enum InitEunm1 {
APPLE{
public void getInfo(){
//TODO……
}
},
BANANA{
public void getInfo(){
//TODO……
}
},
PEAR{
public void getInfo(){
//TODO……
}
};
public abstract void getInfo();
}
如上,我们可通过enum实例来调用自定义方法,如上代码成为"表驱动的代码"(这个参见java编程思想);如上代码可以看出,enum被当成超类来使用,在调用getInfo()方法时体现了多态的特性,所以说,enum和常规的类很相似。
1.6 enum的构造器
enum的构造器和常规类基本一致,就一般的enum而言,往往会定义为private类型类限制它的可访问性。其实这个private加不加都是一样,我们都只能在enum的内部利用构造器来实例化,编译器不允许在除了enum定义结束之外的地方使用其构造器来创建实例。
在idea中,倘若我们定义了private的构造方法,idea会自动识别
2.1 enum结合switch
在switch语句中使用enum时enum提供的一项非常便利的功能,在switch的条件中支持的类型有int、char、short、byte、Enum
public enum InitEunm1 {
YES, NO;
public static void main(String[] args) {
InitEunm1 orderStatus = InitEunm1.YES;
switch (orderStatus) {
case YES: //TODO ……;
case NO: //TODO ……;
default:
}
}
}
3.1 EnumSet
Set是有序不可重复的集合,EnumSet显然就是专为enum设计的高效的集合(内部将long值作为比特向量);EnumSet中的元素必须来自于enum
public enum InitEnum {
YES, NO, OK;
public static void main(String[] args) {
EnumSet set = EnumSet.allOf(InitEnum.class);
Iterator<EnumSet> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
3.2 EnumMap
EnumMap是一种特殊的Map,它要求key必须来自于enum实例
public enum InitEnum {
YES, NO, OK;
public static void main(String[] args) {
//EnumMap的key必须是枚举实例
EnumMap<InitEnum, String> map = new EnumMap<InitEnum, String>(InitEnum.class);
map.put(InitEnum.YES, "YES");
map.put(InitEnum.NO, "NO");
map.put(InitEnum.OK, "OK");
for (Map.Entry<InitEnum, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "-->" + entry.getValue());
}
}
}
以下这三种方式定义常量的区别?
public class Constants {
// 方式一:实体类中定义常量
public static final String ORDER_SUCCESS = "success";
public static final String ORDER_FAIL = "fail";
//方式二:接口中定义常量
public interface ORDER{
String ORDER_SUCCESS = "success";
String ORDER_FAIL = "fail";
}
//方式三:enum中定义常量
public enum Consts{
ORDER_SUCCESS(0,"success"),ORDER_FAIL(-1,"fail");
private Integer code;
private String desc;
Consts(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
public Integer getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
}
在接口中定义的常量默认就是static final类型的,所以不需要再显式的加static final修饰;接口中定义常量往往会给我们包含一种组别的概念,方便分类维护。