Java Enum用法小结

用法一:常量

在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

public enum Color {  
  RED, GREEN, BLANK, YELLOW  


用法二:switch

JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Signal {
        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 实例。

package myEnum.test;

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;
}

}

用法四:使用接口组织枚举

所有的枚举都继承自java.lang.Enum类,由于Java 不支持多继承,所以枚举对象不能再继承其他类;对于enum而言,实现接口是其实现子类化的唯一办法。
package myEnum.test;


/**   
 * @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;
}
}
}

小结:

0、enum枚举类型是一个不可以被继承的final类
1、values()方法可用来返回接口中的一个数组,即该枚举中定义的常量枚举;
2、name()方法会返回当前枚举值的名字。
常用的几个方法:
public final String name()//返回枚举常量的名称; 

public final int ordinal()//返回枚举常量在枚举类型中的位置,第一个枚举值序号为0,依次类推; 

public String toString()//返回枚举常量的名字,可以重写此方法; 

public static valueOf(enumType,String name)//返回与name名字相对应的枚举常量;


用法五:应用枚举定义一个类映射到数据库表(转载)

http://www.oschina.net/question/54100_21934


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{
     ....
}
然后注释掉我们前面提到的 name() 方法:

?
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 类一样来使用枚举类型。


用法六:枚举泛型使用(转载)

http://www.myexception.cn/program/1586060.html

对于enum而言,实现接口是其实现子类化的唯一办法。在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组,可以达到将枚举元素分类组织的目的。如下示例,用enum来表示不同类别的食物,但同时希望每个enum元素仍然保持Food类型。
   
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 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是一个枚举实例。将Class作为参数,就可以利用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 random(Class ec) {
    return random(ec.getEnumConstants());
  }
  public static  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实例得到“枚举的枚举”的值。

你可能感兴趣的:(enum)