在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
public enum Color {
RED, GREEN, BLANK, YELLOW
}
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
Java 中一个典型的枚举类型,看似字符串值,但包含一些附加的信息,包括排序以及附加的方法可以获取枚举值的信息。
下面是一个基本的枚举类型:
1
|
public
enum
Suit { CLUBS, DIAMONDS, HEARTS, SPADES }
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
enum
Numbers {
One(
1
), Two(
2
), Three(
3
);
private
Numbers(
int
value)
{
this
.value = value;
}
public
int
getValue()
{
return
this
.value;
}
private
int
value;
}
|
在上面的例子中,我们引入了 getValue() 方法,这便是枚举的行为定义。
接下来我们要做的是枚举类型对接口的继承以及实际的用途。
为了显示工作过程,我们首先做一个接口,用来实现类和数据库表的一个映射:
1
2
3
4
5
6
|
public
interface
DatabaseMapping {
public
String getType();
public
boolean
isKey();
public
boolean
isNullable();
//public String name();
}
|
name() 方法这个时候被注释掉,待会我们会取消注释。
接下来我们创建一个新的 Java 类用以定义和数据库之间的映射关系:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public
class
Person {
public
String getFirstname() {
return
firstname;
}
public
void
setFirstname(String firstname) {
this
.firstname = firstname;
}
public
String getLastname() {
return
lastname;
}
public
void
setLastname(String lastname) {
this
.lastname = lastname;
}
public
int
getAge() {
return
age;
}
public
void
setAge(
int
age) {
this
.age = age;
}
private
String firstname;
private
String lastname;
private
int
age;
}
|
然后我意识到了,其实有更好的方法来映射一个类到数据库表,上面这个例子很做作。当我们定义了映射到表的类时,我们需要定义一个独立的映射类,但实际上用枚举更好,数据库表中的字段可以是枚举的成员。
例如下面这样写不是更简单吗?
1
2
3
|
public
enum
PersonMapping {
personId, firstname, lastname, age;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public
enum
PersonMapping {
personId(
"INTEGER"
,
true
,
false
),
firstname(
"TEXT"
,
false
,
false
),
lastname(
"TEXT"
,
false
,
false
),
age(
"INTEGER"
,
false
,
false
);
private
PersonMapping(String type,
boolean
key,
boolean
nullable )
{
this
.type = type;
this
.key = key;
this
.nullable = nullable;
}
public
String getType() {
return
type;
}
public
boolean
isKey() {
return
key;
}
public
boolean
isNullable() {
return
nullable;
}
private
final
String type;
private
final
boolean
key;
private
final
boolean
nullable;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
String dbTableCreate(String tableName) {
StringBuilder builder =
new
StringBuilder(
"Create table "
);
builder.append(tableName);
builder.append(
"("
);
for
(PersonMapping column : PersonMapping.values()) {
builder.append(column.name());
builder.append(
" "
);
builder.append(column.getType());
builder.append(column.isKey() ?
" primary key"
:
""
);
builder.append(
", "
);
}
builder =
new
StringBuilder(builder.substring(
0
, builder.length() -
2
));
builder.append(
");"
);
return
builder.toString();
}
|
这个 PersonMapping 枚举类型看起来不错,但是它不允许我们使用不同的类到数据库的映射,因此我们需要抽象,需要接口。从上面的代码看,我们需要枚举类型两个通过的方法:name() 和 values(),第一个方法返回当前枚举值的名字,第二个就是列出所有的枚举值。
首先,我们为枚举添加一个接口:
1
2
3
|
public
enum
PersonMapping
implements
MappingEnum{
....
}
|
1
2
3
4
5
6
|
public
interface
MappingEnum {
public
String getType();
public
boolean
isKey();
public
boolean
isNullable();
public
String name();
}
|
最后我们编写一个 dbTableCreate() 方法来让其他的枚举类型可重用这个方法:
1
|
dbTableCreate(
"tableName"
, PersonMapping.values()));
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
String dbTableCreate(String tableName, MappingEnum[] values) {
StringBuilder builder =
new
StringBuilder(
"Create table "
);
builder.append(tableName);
builder.append(
"("
);
for
(MappingEnum column : values) {
builder.append(column.name());
builder.append(
" "
);
builder.append(column.getType());
builder.append(column.isKey() ?
" primary key"
:
""
);
builder.append(
", "
);
}
builder =
new
StringBuilder(builder.substring(
0
, builder.length() -
2
));
builder.append(
");"
);
return
builder.toString();
}
|
总而言之,你可以像使用普通 Java 类一样来使用枚举类型。
package enumerated.menu;
import net.mindview.util.*;
public enum Meal2 {
APPETIZER(Food.Appetizer.class), MAINCOURSE(Food.MainCourse.class), DESSERT(
Food.Dessert.class), COFFEE(Food.Coffee.class);
private Food[] values;
private Meal2(Class extends Food> kind) {
values = kind.getEnumConstants();
}
public interface Food {
enum Appetizer implements Food {
SALAD, SOUP, SPRING_ROLLS;
}
enum MainCourse implements Food {
LASAGNE, BURRITO, PAD_THAI, LENTILS, HUMMOUS, VINDALOO;
}
enum Dessert implements Food {
TIRAMISU, GELATO, BLACK_FOREST_CAKE, FRUIT, CREME_CARAMEL;
}
enum Coffee implements Food {
BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, LATTE, CAPPUCCINO, TEA, HERB_TEA;
}
}
public Food randomSelection() {
return Enums.random(values);
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
for (Meal2 meal : Meal2.values()) {
Food food = meal.randomSelection();
System.out.println(food);
}
System.out.println("---");
}
}
}
//: net/mindview/util/Enums.java
package net.mindview.util;
import java.util.*;
public class Enums {
private static Random rand = new Random(47);
public static > T random(Class ec) {
return random(ec.getEnumConstants());
}
public static T random(T[] values) {
return values[rand.nextInt(values.length)];
}
} ///:~