0%

枚举类型

枚举类型

创建 enmu时, 编译器会为你生成一个相关的类, 这个类继承自java.lang.Enum. 但是这个新生成的类是final的,不能为继承

如果在emum()实例上调用getDeclaringClass()方法,我们就能知道其所属的enum()类.

向enum 中添加新方法

如果打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号.同时必须先定义enum实例.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public enum Color {
RED(255, 0, 0);
Color(int r, int b, int g) {
this.r = r;
this.b = b;
this.g = g;
}
private int r;
private int b;
private int g;

public int getRed() {
return r;
}
//... etc

@Override
public String toString() {
return "the rbg is {" + r +", " + b + ", " + g + "}";
}
}

switch 语句中的enum

实际上,在编译器中会通过ordinal()方法取得其次序.

values()的神秘之处

通过反射我们会发现Enum类,它并没有values()方法.

values方法是由编译器添加的static方法.编译器还会为其添加了valueOf()方法.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public enum Main {
RED(255, 0, 0);
Main(int r, int b, int g) {
this.r = r;
this.b = b;
this.g = g;
}
private int r;
private int b;
private int g;

public int getRed() {
return r;
}
//... etc

@Override
public String toString() {
return "the rbg is {" + r +", " + b + ", " + g + "}";
}
}

经过 javap Main 之后之后

1
2
3
4
5
6
7
8
public final class Main extends java.lang.Enum<Main> {
public static final Main RED;
public static Main[] values();
public static Main valueOf(java.lang.String);
public int getRed();
public java.lang.String toString();
static {};
}

由于擦除效应,反编译无法得到Enum的完整信息,所以它展示的Main的父亲类只是一个原始的Enum, 而并非事实上的Enum.

由于values()方法是由编译器插入到enum定义的中断饿static方法. 如果上转型Enum, 那么values()就不能访问了. 不过class类中有getEnumConstants()方法,可以得到所有enum实例.

使用EnumMap

EnumMap 是一种特殊的Map, 它要求其中的key必须来自于一个enum. 由于enum本身的限制,所以EnumMap在内部可以由数组实现. 比方说 Enum ordinal的值是0, 那么arr[0] 就是enumMap.get(Enum.something)对应的值.

常量相关的方法

Java 的enum有个非常有趣特性,他允许程序员为enum实例编写方法,从而为每个enum实例赋予各自不同的行为.

1
2
3
4
5
6
7
8
9
public enum ConstantSpecificMethod {
DATE_TIME {
String getInfo() {
return "I AM DATE_TIME";
}
};

abstract String getInfo();
}

606