用法一:常量
在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。
public enum Color {
RED, GREEN, BLANK, YELLOW
}
用法二:switch
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
用法三:向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
public enum TestMyEnum {
ONE("1",1,1.2),TWO("2",2,3.4);
private String name;
private int age;
private double weight;
private TestMyEnum(String name, int age, double weight) {
this.name = name;
this.age = age;
this.weight = weight;
}
@Override
public String toString() {
return "age=" + age + ", weight=" + weight;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
}
用法四:使用接口组织枚举
/**
* @Description: TODO
* @author wangy
* @date 2016年1月12日 下午10:05:39
*/
public interface ITestMyEnum {
public String getDescription() ;
public enum Fruit implements ITestMyEnum{
Apple(1,"red"), Orange(3,"yellow"), banana(4,"yellow");
private Fruit(int weight, String description) {
this.weight = weight;
this.description = description;
}
private int weight;
private String description;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
public enum Food implements ITestMyEnum{
Rice(1,"whit"), Meat(3,"red"), Corn(4,"yellow");
private Food(int weight, String description) {
this.weight = weight;
this.description = description;
}
private int weight;
private String description;
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
}
小结:
public final int ordinal()//返回枚举常量在枚举类型中的位置,第一个枚举值序号为0,依次类推;
public String toString()//返回枚举常量的名字,可以重写此方法;
public static valueOf(enumType,String name)//返回与name名字相对应的枚举常量;
用法五:应用枚举定义一个类映射到数据库表(转载)
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 类无异
- values() 方法可用来返回接口中的一个数组
总而言之,你可以像使用普通 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("---");
}
}
}
下面是Enums工具类,实现从枚举实例中随机选择,<T extends Enum<T>>表示T是一个枚举实例。将Class<T>作为参数,就可以利用Class对象得到enum实例的数组了。重装后的random()方法只需要使用T[]作为参数,它从数组中随机选择一个元素。
//: 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 extends Enum<T>> T random(Class<T> ec) {
return random(ec.getEnumConstants());
}
public static <T> T random(T[] values) {
return values[rand.nextInt(values.length)];
}
} ///:~
输出结果:
SPRING_ROLLS
VINDALOO
FRUIT
DECAF_COFFEE
---
SOUP
VINDALOO
FRUIT
TEA
---
SALAD
BURRITO
FRUIT
TEA
---
SALAD
BURRITO
CREME_CARAMEL
LATTE
---
SOUP
BURRITO
TIRAMISU
ESPRESSO
---
嵌入在Food中的每个enum都实现了Food接口,该接口的作用就是将其所包含的enum组合成一个公共类型,这一点是必要的。然后Meal2才能将Food中的enum作为构造器参数使用,每一个Meal2实例都将其对应的class实例对象作为构造器参数。通过getEnumConstants()方法,可以取得某个Food子类的所有enum实例。这些实例在randomSelection中被用到。因此可以从Meal2实例中随机选择一个Food,生成一份菜单。我们通过遍历每一个Meal2实例得到“枚举的枚举”的值。