枚举是java5后新增加的特性,是一种特殊的数据类型,特殊是因为枚举是一种类(class)类型,但是比class类型多了一些约束,下面就看看什么是枚举,枚举的定义和使用。
1、枚举的好处
在java5以前经常使用常量类来统一定义常量如下所示。常量类大家应该都是知道的,常量类存在以下不足:因为int型的赋值范围是随意的,即blue可以为1,black也可以为1,那么在定义常量多时难免会有混淆。
class ConstantClass {//代码1
public static final int blue = 1;
public static final int yellow = 2;
public static final int red = 3;
public static final int green = 4;
public static final int white = 5;
public static final int black = 6;
}
针对常量类中的缺陷,枚举可以加以优化,可以看看下面定义的枚举类,以结果证明其常量值是不会有重复,枚举的解决办法就是给每个常量给一个名字。
public class EnumDemo {//代码2
public static void main(String[] args) {
for (Color c : Color.values()) {// values()方法是获取Color所有的枚举值,所组成的数组
System.out.println(c.name());
}
}
}
enum Color {
blue,yellow,red,green,white,black;
}
输出结果:
yellow
red
green
white
black
从输出结果可以看到,相比于常量类的多个int常量,枚举值可以有唯一的名字,避免重复混淆,保证常量的唯一性。这就是枚举的优势所在。其实就是规范了参数形式。
2、枚举的定义
当然,你也可以定义自己想要的枚举,并做好安全性封装,简单看一下下面代码以及会存在的一些问题:
public class EnumDemo2 {// 代码3
public static void main(String[] args) {
System.out.println(Week.MONDAY.getValue());// MONDAY是static的
Week.MONDAY.setValue("aaaa");
System.out.println(Week.MONDAY.getValue());
}
}
enum Week { MONDAY("MON", 1),TUESDAT("TUES", 2),WEDNESDAY("WED", 3),THURSDAY("THURS", 4); public String value;// 枚举值是用作的常量的,注意权限问题。public型的是可以在类外部进行修改的,应改为private public Integer typeId;
Week(String value, Integer typeId) {// 构造函数应该默认为私有。外部新建枚举类可以调用valueOf()方法,后面会讲 this.setValue(value); this.setTypeId(typeId); } public String getValue() { return value; } public void setValue(String value) {// 不要留外部修改枚举值的接口,应该删除 this.value = value; } public Integer getTypeId() { return typeId; } public void setTypeId(Integer typeId) { this.typeId = typeId; }}
输出结果如下,可以看出枚举值被修改了,这样的枚举类安全性是有严重问题的,再者新定义的MONDAY等枚举类是static的,外面是可以直接访问的:
MON
aaaa
下面写了一个正确的枚举类:
public class EnumDemo2 { //代码4
public static void main(String[] args) {
System.out.println(Week.MONDAY.getValue());
}
}
enum Week {
MONDAY("MON", 1),TUESDAT("TUES", 2),WEDNESDAY("WED", 3),THURSDAY("THURS", 4);
private String value;
private Integer typeId;
Week(String value, Integer typeId) {
this.value = value;
this.typeId = typeId;
}
public String getValue() {
return value;
}
public Integer getTypeId() {
return typeId;
}
}
2、枚举中的常用方法:
(1)values()方法:这个已经在代码2中使用了,该方法是返回一个数组,数组中的值即是当前枚举类下所有的枚举值。
(2)ordinal()方法:返回枚举常量的序数:
public class EnumDemo {//代码5
public static void main(String[] args) {
System.out.println(Color.BLUE.ordinal());// 返回枚举常量的序数
}
}
enum Color {
BLUE,yellow,red,green,white,black;
}
输出:
0
(3)valueOf()方法:方法返回指定名称的枚举常量
package com.zy.test;
enum Grade {
A("90-100"),B("80-89"),C("70-79"),D("60-69"),E("0-59");
private String value;
private Grade(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public class EnumDemo {
public static void main(String[] args) {
Grade g = Grade.valueOf(Grade.class, "B");// 返回带指定名称的指定枚举类型的枚举常量。有一点必须注意这个枚举常量必须是已定义的
System.out.println(g.getValue());// 返回枚举B中的值
}
}
输出结果:
80-89
3、枚举的扩充——代抽象方法的枚举
直接上代码:
package com.zy.test;
public class EnumDemo {
public static void main(String[] args) {
System.out.println(GradeTest.B.local());// 返回实现抽象方法的结果
}
}
/**
* 带抽象方法的枚举
* @author user
*
*/
enum GradeTest {
A("90-100") {
public String local() {
return "优";
}
}
,B("80-89") {
public String local() {
return "良";
}
}
,C("70-79") {
public String local() {
return "中";
}
},D("60-69"){
public String local() {
return "差";
}
},E("0-59")
{
public String local() {
return "优";
}
};
private String value;
private GradeTest(String value) {
this.value = value;
}
public String getValue() {
return value;
}
abstract public String local();
}
输出结果:
良
上面的只是java枚举的基本使用,后续再深入!