用法一:常量
在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实例得到“枚举的枚举”的值。