JAVA基础——枚举详解

前言:



  在第一次学习面向对象编程时,我记得最深的一句话就是“万物皆对象”。于是我一直秉承着这个思想努力的学习着JAVA,直到学习到枚举(Enum)时,看着它颇为奇怪的语法……我一直在想,这TM是个什么鬼???当时学习OOP时也是被类啊接口什么的整的有点昏头转向的于是就把这个小细节忽略掉了。后来到了公司工作后慢慢的又需要用上枚举了,看着它一副神秘兮兮的样子我还是决定要好好的深挖一下!以下链接是了解枚举时所参考的博客。如发现本文有错误或知识遗漏欢迎在评论中指正!

  反编译那些事儿(二)—枚举的反编译:http://blog.csdn.net/gaohuanjie/article/details/18140279

  JAVA枚举与常量类的区别:http://blog.csdn.net/tanqian351/article/details/53736628

目录:



   1)历史

  2)语法解析

  3)枚举的好处以及与常量类的区别

  4)枚举常用方法

1.历史:



  枚举是JDK1.5版本新增的特性(泛型、For-each等如今被广泛应用的特性也是由JDK1.5时所新增的),另外到了JDK1.6后switch语句支持枚举类型。

2.枚举的语法解析:



  1.最最最简单版

public enum ColorEnum {
	RED,BLUE,GREEN
}

  通过工具解析class后获得的源代码(工具参考上面的链接)

public final class ColorEnum extends Enum
{

    //返回存储枚举实例的数组的副本。values()方法通常用于foreach循环遍历枚举常量。
    public static ColorEnum[] values()
    {
        return (ColorEnum[])$VALUES.clone();
    }
    //根据实例名获取实例
    public static ColorEnum valueOf(String s)
    {
        return (ColorEnum)Enum.valueOf(ColorEnum, s);
    }

    //私有构造方法,这里调用了父类的构造方法,其中参数s对应了常量名,参数i代表枚举的一个顺序(这个顺序与枚举的声明顺序对应,用于oridinal()方法返回顺序值)
    private ColorEnum(String s, int i)
    {
        super(s, i);
    }

    //我们定义的枚举在这里声明了三个 ColorEnum的常量对象引用,对象的实例化在static静态块中
    public static final ColorEnum RED;
    public static final ColorEnum BLUE;
    public static final ColorEnum GREEN;
    //将所有枚举的实例存放在数组中
    private static final ColorEnum $VALUES[];

    static
    {
        RED = new ColorEnum("RED", 0);
        BLUE = new ColorEnum("BLUE", 1);
        GREEN = new ColorEnum("GREEN", 2);
        //将所有枚举的实例存放在数组中
        $VALUES = (new ColorEnum[] {
            RED, BLUE, GREEN
        });
    }
}

  2.现在我们在枚举类中增加自己的字段以及一些辅助方法,代码如下:

public enum ColorEnum {
    RED("red","红色"),GREEN("green","绿色"),BLUE("blue","蓝色");
    //防止字段值被修改,增加的字段也统一final表示常量
    private final String key;
    private final String value;

    private ColorEnum(String key,String value){
        this.key = key;
        this.value = value;
    }
    //根据key获取枚举
    public static ColorEnum getEnumByKey(String key){
        if(null == key){
            return null;
        }
        for(ColorEnum temp:ColorEnum.values()){
            if(temp.getKey().equals(key)){
                return temp;
            }
        }
        return null;
    }
    public String getKey() {
        return key;
    }
    public String getValue() {
        return value;
    }
}

  老规矩,反编译看看变化?(其实也就看看static静态块和构造方法有什么变化就好了)

public final class ColorEnum extends Enum
{

    public static ColorEnum[] values()
    {
        return (ColorEnum[])$VALUES.clone();
    }

    public static ColorEnum valueOf(String s)
    {
        return (ColorEnum)Enum.valueOf(ColorEnum, s);
    }

    //构造方法在原基础上加上我们新增的两个形参
    private ColorEnum(String s, int i, String s1, String s2)
    {
        super(s, i);
        key = s1;
        value = s2;
    }

    //自定义方法,通过key值获得对应的枚举对象
    public static ColorEnum getEnumByKey(String s)
    {
        if(null == s)
            return null;
        ColorEnum acolorenum[] = values();
        int i = acolorenum.length;
        for(int j = 0; j < i; j++)
        {
            ColorEnum colorenum = acolorenum[j];
            if(colorenum.getKey().equals(s))
                return colorenum;
        }

        return null;
    }

    public String getKey()
    {
        return key;
    }

    public String getValue()
    {
        return value;
    }

    public static final ColorEnum RED;
    public static final ColorEnum GREEN;
    public static final ColorEnum BLUE;
    //我们自定义的两个字段
    private final String key;
    private final String value;
    private static final ColorEnum $VALUES[];

    static
    {
        RED = new ColorEnum("RED", 0, "red", "\u7EFE\u3223\u58CA");
        GREEN = new ColorEnum("GREEN", 1, "green", "\u7F01\u80EF\u58CA");
        BLUE = new ColorEnum("BLUE", 2, "blue", "\u9483\u6FCA\u58CA");
        $VALUES = (new ColorEnum[] {
            RED, GREEN, BLUE
        });
    }
}

3.枚举的好处以及与常量类的区别



  1)枚举型可以直接与数据库打交道,我通常使用varchar类型存储,对应的是枚举的常量名。(数据库中好像也有枚举类型,不过也没用过)

  2) switch语句支持枚举型,当switch使用int、String类型时,由于值的不稳定性往往会有越界的现象,对于这个的处理往往只能通过if条件筛选以及default模块来处理。而使用枚举型后,在编译期间限定类型,不允许发生越界的情况

  3) 当你使用常量类时,往往得通过equals去判断两者是否相等,使用枚举的话由于常量值地址唯一,可以用==直接对比,性能会有提高

  4) 常量类编译时,是直接把常量的值编译到类的二进制代码里,常量的值在升级中变化后,需要重新编译引用常量的类,因为里面存的是旧值。枚举类编译时,没有把常量值编译到代码里,即使常量的值发生变化,也不会影响引用常量的类。

  5)枚举类编译后默认为final class,不允许继承可防止被子类修改。常量类可被继承修改、增加字段等,容易导致父类的不兼容。

  

………………欢迎补充!

  总结:常量的定义在开发中是必不可少的,虽然无论是通过常量类定义常量还是枚举定义常量都可以满足常量定义的需求。但个人建议最好是使用枚举类型。

4.枚举常用方法



  1.values()获取存储枚举中所有常量实例的数组。常配合foreach完成遍历

    for(ColorEnum temp:ColorEnum.values()){
            System.out.println(temp);
    }

  运行结果:

  RED
  GREEN
  BLUE

  2.构造方法,枚举的构造方法只能用private修饰符修饰,原因就不需要解释了……

  3.valueOf()通过常量名获取对应的枚举实例。

  ColorEnum red = ColorEnum.valueOf("RED");  System.out.println(red);
时间: 2024-10-03 23:46:58

JAVA基础——枚举详解的相关文章

JAVA基础——内部类详解

JAVA内部类详解 在我的另一篇java三大特性的封装中讲到java内部类的简单概要,这里将详细深入了解java内部类的使用和应用. 我们知道内部类可分为以下几种: 成员内部类 静态内部类 方法内部类 匿名内部类 这里我们先将以这个分类来详细了解各个内部类的情况.然后给内部类作出总结. 一.成员内部类 内部类中最常见的就是成员内部类,也称为普通内部类.我们来看如下代码: 运行结果为: 从上面的代码中我们可以看到,成员内部类的使用方法: 1. Inner 类定义在 Outer 类的内部,相当于 O

JAVA基础——异常详解

阅读目录 一.异常简介 二.try-catch-finally语句 三.throw和throws关键字 四.java中的异常链 五.结束语 JAVA异常与异常处理详解 回到顶部 一.异常简介 什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域的情况,称之为异常. java中异常的体系是怎么样的呢? 1.Java中的所有不正常类都继承于Throwable类.Throwable主要包括两个大类,一个是Error类,另一个是Exception类: 2.其

Java 基础知识详解

由于有C#的基础,Java的基础知识基本是略过,这里当做复习一遍吧! Java的三种技术架构: JavaEE:(Java PlatForm Enterprise Edition) Java开发企业级的应用,主要针对Web JavaSE;(Java PlatForm  Standard Edition) 完成桌面程序的开发,是其他两个的基础 JavaME:(Java PlatForm Micro Edition)开发电子消费产品和嵌入式设备,如Android Java数据类型 (1)基本数据类型(

【夯实基础】java关键字synchronized 详解

尊重版权:http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行.另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块. 二.然而,当一个线程访问object的一个sy

Java多线程编程详解

线程的同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问. 由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是 synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法:通过在方法声明中加入 synch

转:Java HashMap实现详解

Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1.    HashMap概述: HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 2.    HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造

高性能Web服务之tomcat基础应用详解(一)

Tomcat概述: Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun 和其他一些公司及个人共同开发而成.由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范.因为Tomcat 技术先进.性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目

【转】 java中HashMap详解

原文网址:http://blog.csdn.net/caihaijiang/article/details/6280251 java中HashMap详解 HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实现类.虽然 HashMap 和 HashSet 实现的接口规范不同,但它们底层的 Hash 存储机制完全一样,甚至 HashSet 本身就采用 H

Tomcat基础配置详解

Tomcat基础配置详解 组件原理图如下: 任何tomcat实例就是一个server,而一个server内部要想能够解析jsp页面转义编译serlet程序,要靠其引擎来实现 而引擎才是真正意义上执行jsp代码的容器,都是tomcat用类来描述这些组件的 同时,为了接受用户的请求,需要基于connector组件,所谓监听的套接字的程序,能够接手用户的请求,被称为连接器 一个server内部可以完全运行N个引擎,无非就是运行多个虚拟机而已 war包的概念 放在网页目录可以直接访问,而部署的时候可以自