从没有枚举的时代说起

在枚举出现之前,如果想要表示一组特定的离散值,往往使用一些常量。例如:
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Entity {
 
    public static final int VIDEO = 1;//视频
    public static final int AUDIO = 2;//音频
    public static final int TEXT = 3;//文字
    public static final int IMAGE = 4;//图片
 
    private int id;
    private int type;
 
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
}
当然,常量也不仅仅局限于int型,诸如char和String等也是不在少数。然而,无论使用什么样的类型,这样做都有很多的坏处。这些常量通常都是连续、有无穷多个值的量,而类似这种表示类别的量则是离散的,并且通常情况下只有有限个值。用连续的量去表示离散量,会产生很多问题。例如,针对上述的Entity类,如果要对Entity对象的type属性进行赋值,一般会采用如下方法:
[Java] 纯文本查看 复制代码
1
2
3
Entity e = new Entity();
e.setId(10);
e.setType(2);
这样做的缺点有:
(1)代码可读性差、易用性低。由于setType()方法的参数是int型的,在阅读代码的时候往往会让读者感到一头雾水,根本不明白这个2到底是什么意思,代表的是什么类型。当然,要保证可读性,还有这样一个办法:
e.setType(Entity.AUDIO);
而这样的话,问题又来了。这样做,客户端必须对这些常量去建立理解,才能了解如何去使用这个东西。说白了,在调用的时候,如果用户不到Entity类中去看看,还真不知道这个参数应该怎么传、怎么调。像是setType(2)这种用法也是在所难免,因为它完全合法,不是每个人都能够建立起用常量名代替数值,从而增加程序可读性、降低耦合性的意识。
(2)类型不安全。在用户去调用的时候,必须保证类型完全一致,同时取值范围也要正确。像是setType(-1)这样的调用是合法的,但它并不合理,今后会为程序带来种种问题。也许你会说,加一个有效性验证嘛,但是,这样做的话,又会引出下面的第(3)个问题。
(3)耦合性高,扩展性差。假如,因为某些原因,需要修改Entity类中常量的值,那么,所有用到这些常量的代码也就都需要修改——当然,要仔细地修改,万一漏了一个,那可不是开玩笑的。同时,这样做也不利于扩展。例如,假如针对类别做了一个有效性验证,如果类别增加了或者有所变动,则有效性验证也需要做对应的修改,不利于后期维护。

认识枚举

枚举(enum),是指一个经过排序的、被打包成一个单一实体的项列表。一个枚举的实例可以使用枚举项列表中任意单一项的值。枚举在各个语言当中都有着广泛的应用,通常用来表示诸如颜色、方式、类别、状态等等数目有限、形式离散、表达又极为明确的量。Java从JDK5开始,引入了对枚举的支持。

使用枚举解决我们前面遇到的问题

枚举就是为了这样的问题而诞生的。它们给出了将一个任意项同另一个项相比较的能力,并且可以在一个已定义项列表中进行迭代。枚举(在Jave中简称为enum)是一个特定类型的类。所有枚举都是Java中的新类java.lang.Enum的隐式子类。此类不能手工进行子类定义。一个简单的枚举可以是这样:
[Java] 纯文本查看 复制代码
1
2
3
public enum TypeEnum {
    VIDEO, AUDIO, TEXT, IMAGE
}
上面的Entity类就可以改成这样:
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
public class Entity {
 
    private int id;
    private TypeEnum type;
 
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
 
    public TypeEnum getType() {
        return type;
    }
    public void setType(TypeEnum type) {
        this.type = type;
    }
}
在为Entity对象赋值的时候,就可以这样:
[Java] 纯文本查看 复制代码
1
2
3
Entity e = new Entity();
e.setId(10);
e.setType(TypeEnum.AUDIO);
怎么看,都是好了很多。在调用setType()时,可选值只有四个,否则会出现编译错误,因此可以看出,枚举是类型安全的,不会出现取值范围错误的问题。同时,客户端不需要建立对枚举中常量值的了解,使用起来很方便,并且可以容易地对枚举进行修改,而无需修改客户端。如果常量从枚举中被删除了,那么客户端将会失败并且将会收到一个错误消息。枚举中的常量名称可以被打印,因此除了仅仅得到列表中项的序号外还可以获取更多信息。这也意味着常量可用作集合的名称,例如HashMap。
因为在Java中一个枚举就是一个类,它也可以有属性和方法,并且实现接口。只是所有的枚举都继承自java.lang.Enum类,因此enum不可以再继承其他的类。
下面给出在枚举中声明属性和方法的示例:
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
public enum TypeEnum {
    VIDEO(1), AUDIO(2), TEXT(3), IMAGE(4);
 
    int value;
 
    TypeEnum(int value) {
        this.value = value;
    }
 
    public int getValue() {
        return value;
    }
}
在这个枚举中,每个枚举的值都有一个对应的int型字段,而且不同的枚举值也会有不同的int数值。同时,它和普通的类一样,可以声明构造器和各种各样的方法。如:
[Java] 纯文本查看 复制代码
1
2
TypeEnum type = TypeEnum.TEXT;//type的value属性值为3。
System.out.println(type.getValue());//屏幕输出3。
如果要为每个枚举值指定属性,则在枚举中必须声明一个参数为属性对应类型的构造方法(不能是public)。否则编译器将给出The constructor TypeEnum(int, String) is undefined的错误。在此例中,属性为int型,因此构造方法应当为int型。除此之外,还可以为枚举指定多个属性,如:
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
public enum TypeEnum {
    VIDEO(1, "视频"), AUDIO(2, "音频"), TEXT(3, "文本"), IMAGE(4, "图像");
 
    int value;
    String name;
 
    TypeEnum(int value, String name) {
        this.value = value;
        this.name = name;
    }
 
    public int getValue() {
        return value;
    }
 
    public String getName() {
        return name;
    }
}
enum还内置了许多方法,常用的如下:
[Java] 纯文本查看 复制代码
1
2
3
4
5
6
7
int compareTo(E o) //比较此枚举与指定对象的顺序。
Class<E> getDeclaringClass() //返回与此枚举常量的枚举类型相对应的 Class 对象。
String name() // 返回此枚举常量的名称,在其枚举声明中对其进行声明。
int ordinal() //返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
String toString()//返回枚举常量的名称,它包含在声明中。
static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) //返回带指定名称的指定枚举类型的枚举常量。
static T[] values()//返回该枚举的所有值。
现在,假设要为该枚举实现一个根据整数值生成枚举值的方法,可以这样做:
[Java] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public enum TypeEnum {
    VIDEO(1, "视频"), AUDIO(2, "音频"), TEXT(3, "文本"), IMAGE(4, "图像");
 
    int value;
    String name;
 
    TypeEnum(int value, String name) {
        this.value = value;
        this.name = name;
    }
 
    public int getValue() {
        return value;
    }
 
    public String getName() {
        return name;
    }
 
    public static TypeEnum getByValue(int value) {
        for(TypeEnum typeEnum : TypeEnum.values()) {
            if(typeEnum.value == value) {
                return typeEnum;
            }
        }
        throw new IllegalArgumentException("No element matches " + value);
    }
}
getByValue(int)即为整数值转枚举值的方法。调用values()方法获取到该枚举下的所有值,然后遍历该枚举下面的每个值和给定的整数是否匹配,若匹配直接返回,若无匹配值则抛出IllegalArgumentException异常,表示参数不合法,兼有有效性验证的作用。
综上,我们可以看到,在JDK5中新引入的枚举完美地解决了之前通过常量来表示离散量所带来的问题,大大加强了程序的可读性、易用性和可维护性,并且在此基础之上又进行了扩展,使之可以像类一样去使用,更是为Java对离散量的表示上升了一个台阶。因此,如果在Java中需要表示诸如颜色、方式、类别、状态等等数目有限、形式离散、表达又极为明确的量,应当尽量舍弃常量表示的做法,而将枚举作为首要的选择。
更多技术资讯可关注:itheimaGZ获取

Java枚举的作用和用法的更多相关文章

  1. 【转】Java 枚举7常见种用法

    原文网址:http://softbeta.iteye.com/blog/1185573 Java 枚举7常见种用法 博客分类: java java枚举enmu  原创地址:http://blog.li ...

  2. Java 枚举常见7种用法

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

  3. 浅谈在Java开发中的枚举的作用和用法

    枚举(enum),是指一个经过排序的.被打包成一个单一实体的项列表.一个枚举的实例可以使用枚举项列表中任意单一项的值.枚举在各个语言当中都有着广泛的应用,通常用来表示诸如颜色.方式.类别.状态等等数目 ...

  4. Java 枚举7常见种用法

    DK1.5引入了新的类型--枚举.在 Java 中它虽然算个"小"功能,却给我的开发带来了"大"方便. 用法一:常量 在JDK1.5 之前,我们定义常量都是:  ...

  5. Java 枚举7种常见用法

    (转)原创地址:http://blog.lichengwu.cn/java/2011/09/26/the-usage-of-enum-in-java/ JDK1.5引入了新的类型--枚举.在 Java ...

  6. Java枚举常见7种用法

    DK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便.用法一:常量在JDK1.5 之前,我们定义常量都是: publicstaticfianl…… .现 ...

  7. Java枚举7常见种用法

    DK1.5引入了新的类型——枚举.在Java中它虽然算个“小”功能,却给我的开发带来了“大”方便. 方法/步骤 用法一:常量 在JDK1.5之前,我们定义常量都是:publicstaticfianl. ...

  8. Java 枚举7常见种用法(转)

    JDK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl ...

  9. java枚举类的常见用法

    枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似的值包含到一种类型当中.而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的定义相似.不过相比 ...

随机推荐

  1. 使用py-faster-rcnn训练自己的数据集

    https://www.jianshu.com/p/a672f702e596 本文记录了在ubuntu16.04下使用py-faster-rcnn来训练自己的数据集的大致过程. 在此之前,已经成功配置 ...

  2. chenzl

    大噶好!我是计算机6班的陈志良.我是一名代码小白.大一才刚接触代码,我发现我对编程兴趣挺大.特别是每周的代码作业,特别具有挑战性,每当我AC一道,我内心都会有自豪感和兴奋感,尽管过程有挫折,但我仍然坚 ...

  3. Innodb-内存架构与特性

    参考文档 Innodb特性buffer_pool http://mysql.taobao.org/monthly/2017/05/01/?spm=a2c4e.11153940.blogcont2812 ...

  4. 吴裕雄--天生自然 PHP开发学习:魔术常量

    <?php echo '这是第 " ' . __LINE__ . ' " 行'; ?> <?php echo '该文件位于 " ' . __FILE__ ...

  5. Acunetix WVS安全测试软件使用教程(入门级)

    1.下载 Acunetix WVS 10.5软件,下载地址为:https://pan.baidu.com/s/1Koku0Lhya5PgphMVL7w19g 密码:v438 2.压缩包中有破解说明,按 ...

  6. 884A. Book Reading#抽空学习好孩子(模拟)

    题目出处:http://codeforces.com/problemset/problem/884/A 题目大意:每天时间分两部分,工作和学习,工作优先,闲暇读书,问第几天读完 #include< ...

  7. 计量经济与时间序列_ACF与PACF标准差(均标准误)的计算(含代码)

    1   我们对于acf和pacf值计算完毕之后,在需要计算两个数值的标准差. 2   acf和pacf的标准差计算略有不同.acf的标准差是一个移动过程,而pacf是一个相对固定过程. 3   我们继 ...

  8. tmp == emg.经典+47

    zw.Y3s3{ttqtf**9q+{xx//up qm+Y3#9t%sfsfqtf+&* hh-Y@15zq&zf51"qt3+x>y ====== 城隍庙 经典景点 ...

  9. Springboot配置注入

    springboot中如何将yml 配置文件中配置,在类中注入使用 ①第一种使用@value方式 ################## 配置文件 ######################### d ...

  10. 再来看看Java8的新特征——lambda表达式

    什么是lambda表达式? 可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表.函数主体.返回类型,可能还有一个可以抛出的异常列表. 比如说new一个Thr ...