Java枚举类型enum

枚举的语法
1.Enum的全称为enumeration,中文俗称枚举类,学过C/C++等语言的人,应该都对它略知一二。
    但在Java语言规范中,是在JDK 5版本中才引入的,存放在 java.lang 包中。在Java版的Enum实质是语法糖,其声明方式如下:

【代码1】

package com.enumtest;
public enum Color
{
    RED,BLUE,BLACK,YELLOW,GREEN   //注意这里可以没有分号
}   

  enum是用来声明枚举的关键字,声明定义的类都隐含继承了一个父类(java.lang.Enum<E>),因此枚举不能再继承,但仍可实现接口。
    该父类有两个私有属性name(枚举类型的名称)和ordinal(枚举实例被创建的序数),分别通过name()和ordinal()暴露出来了.
    定义在枚举类型里的每一个枚举实例都将映射到Enum的子类中,其实例的名称和在枚举类型里定义的顺序都会传入到这个构造函数里 : protected Enum(String name, int ordinal)。
2.如果想更清楚了解一下Enum,可以用反编译工具把自己定义的枚举反编译一下就一目了然了,它就是一个普通的类,只是Java语言规范从Code角度进行了限制,执行javap com.enumtest.Color命令如下:
【代码2】

package com.enumtest;
  public final class Color extends  java.lang.Enum{
    public static final Color RED;
    public static final Color BLUE;
    public static final Color BLACK;
    public static final Color YELLOW;
    public static final Color GREEN;
    static {};
    public static Color[] values();
    public static Color valueOf(java.lang.String);
} 

3.所有枚举类都继承了Enum的方法,下面我们详细介绍这些方法。
(1) ordinal()方法: 返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定。
    Color.RED.ordinal(); //返回结果:0
    Color.BLUE.ordinal(); //返回结果:1
(2) compareTo()方法: Enum实现了java.lang.Comparable接口,因此可以比较象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。(具体可见源代码)
    Color.RED.compareTo(Color.BLUE); //返回结果 -1
(3) values()方法: 静态方法,返回一个包含全部枚举值的数组。
    Color[] colors=Color.values();
    for(Color c:colors){
        System.out.print(c+",");
    }//返回结果:RED,BLUE,BLACK YELLOW,GREEN,
(4) toString()方法: 返回枚举常量的名称。
    Color c=Color.RED;
    System.out.println(c);//返回结果: RED
(5) valueOf()方法: 这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量。
    Color.valueOf("BLUE"); //返回结果: Color.BLUE
(6) equals()方法: 比较两个枚举类对象的引用。
4. 如果定义的枚举有自己的构造函数必须声明私有的。

5. 注意以下区别:
【代码3】

enum Color3{}

enum Color4
{
    RED
}

enum Color5
{
    RED;
}

enum Color6
{
    RED;
    public void test(){}
}

enum Color7
{
    public void test(){}
   // RED;  //错误!!!!
}

enum Color8
{
    ;
    public void test(){}
}

在enum Color3中是一个空的枚举;在enum Color4和Color5中有一个RED的枚举值,后面可以加分号或者不加分号;如果在枚举值后面添加方法,那么在枚举值的最后添加一个分号,如enum Color6;如果像enum Color7一样想把枚举值定义在方法后面是非法的,编译器会提示错误;当然也可以像enum Color8一样定义,注意方法test()之前的分号。

枚举的用法
(1) 常用于对同一类常量进行分类。见代码1.
(2) 声明接口方法时,输入参数类型采用枚举比用原始类型值常量更严谨.
(3) 常量有时往往不仅仅只是一个值,有可能会包含多个属性,此时很适合用枚举
(4) 有时常量对象需要从配置文件中读取其描述信息或者UI显示信息,此时也适合用枚举
(5) 从Java语法层面来说,枚举可以在switch使用,在if中可直接进行比较 。
【代码4】

package com.enumtest;

public enum Color
{
    RED,BLUE,BLACK,YELLOW,GREEN; //注意这里有分号

    public static void valuePrint(Color color)
    {
        switch(color)
        {
            case RED:
                System.out.println(RED);
                break;
            case BLUE:
                System.out.println(BLUE);
                break;
            case BLACK:
                System.out.println(BLACK);
                break;
            case YELLOW:
                System.out.println(YELLOW);
                break;
            case GREEN:
                System.out.println(GREEN);
                break;
            default:
                break;
        }
    }

    public static void main(String args[])
    {
        Color color = Color.RED;
        valuePrint(color);
        EnumTest.valuePrint(color);
    }
}

class EnumTest
{
    public static void valuePrint(Color color)
    {
        switch(color)
        {
            case RED:
                System.out.println(Color.RED);//注意这里的Color.RED不能写成RED,而case中的必须写成RED。
                break;
            case BLUE:
                System.out.println(Color.BLUE);
                break;
            case BLACK:
                System.out.println(Color.BLACK);
                break;
            case YELLOW:
                System.out.println(Color.YELLOW);
                break;
            case GREEN:
                System.out.println(Color.GREEN);
                break;
            default:
                break;
        }
    }
}

运行结果:

RED
RED

(6) 声明枚举属性时最好用public final修饰,使用起来会非常方便
(7) 自定义枚举时,建议不要使用自带的name()和ordinal()方法返回值来与原始值类型转换,这样业务不依赖其枚举的名字和顺序
【代码5】

package com.enumtest;

public enum Color2
{
    RED("红色",1),BLUE("蓝色",2),BLACK("黑色",3),YELLOW("黄色",4),GREEN("绿色",5);

    public final String name;
    public final int index;

    private Color2(String name, int index)
    {
        this.name = name;
        this.index = index;
    }

    public static String getName(int index)
    {
        for(Color2 c: Color2.values())
        {
            if(c.getIndex() == index)
            {
                return c.name;
            }
        }
        return null;
    }

    public static void main(String[] args)
    {
        System.out.println(getName(1));
    }

    public String getName()
    {
        return name;
    }

    public int getIndex()
    {
        return index;
    }
}

运行结果:红色
(8) 重载枚举的方法toString
【代码6】

package com.enumtest;

public enum Color2
{
    RED("红色",1),BLUE("蓝色",2),BLACK("黑色",3),YELLOW("黄色",4),GREEN("绿色",5);

    public final String name;
    public final int index;

    private Color2(String name, int index)
    {
        this.name = name;
        this.index = index;
    }

    public static String getName(int index)
    {
        for(Color2 c: Color2.values())
        {
            if(c.getIndex() == index)
            {
                return c.toString();
            }
        }
        return null;
    }

    public static void main(String[] args)
    {
        System.out.println(getName(1));
    }

    @Override
    public String toString()
    {
        return this.index+"_"+this.name;
    }

    public String getName()
    {
        return name;
    }

    public int getIndex()
    {
        return index;
    }
}

(9)实现接口。所有的枚举都继承自java.lang.Enum类。由于java不支持多继承,所以枚举对象不能再继承其他的类。
【代码7】

package com.enumtest;

public interface Behaviour
{
    void print();
    String getInfo();
}

【代码8】

package com.enumtest;

public enum Color9 implements Behaviour
{
    RED("红色",1),BLUE("蓝色",2),BLACK("黑色",3),YELLOW("黄色",4),GREEN("绿色",5);

    public final String name;
    public final int index;

    private Color9(String name, int index)
    {
        this.name = name;
        this.index = index;
    }

    @Override
    public void print()
    {
        System.out.println(this.index+":"+this.name);
    }

    @Override
    public String getInfo()
    {
        return this.name;
    }
}

(10) 可以创建一个enum类,把它看做一个普通的类。除了它不能继承其他类。(Java是单继承,它已经继承了Enum),可以添加其他的方法,覆盖它本身的方法。
(11) values()方法是编译器插入到enum定义中的static方法,所以,当你将enum实例向上转型为父类Enum是,values()就不可访问了。解决办法:在Class中有一个getEnumConstants()方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有的enum实例。
【代码9】

package com.enumtest;

public enum Color
{
    RED,BLUE,BLACK,YELLOW,GREEN; //注意这里有分号

    public void print()
    {
        for(Color c : Color.class.getEnumConstants())
        {
            System.out.println(c.toString());
        }
    }

    public static void main(String args[])
    {
        Color.RED.print();
    }
}

(12) 无法从enum继承子类,如果需要扩展enum中的元素,在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组。达到将枚举元素进行分组。
【代码10】

package com.enumtest;

public interface Food
{
    enum Coffee implements Food
    {
        BLACK_COFFEE, DECAF_COFFEE,LATTE;
    }

    enum Dessert implements Food
    {
        FRUIT,CAKE,GELATO;
    }
}

(13) java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的 key是enum类型,而value则可以是任意类型。
【代码11】

package com.enumtest;

import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Set;

public class LightTest
{
    public enum Light{
        RED(1),GREEN(2),YELLOW(3);

        public final int nCode;

        private Light(int nCode)
        {
            this.nCode = nCode;
        }
    }

    public static void testTraversalEnum()
    {
        Light[] allLight = Light.values();
        for(Light aLight:allLight)
        {
            System.out.println(aLight.name()+" "+aLight.ordinal()+" "+aLight);
        }
    }

    public static void testEnumMap()
    {
        EnumMap<Light,String> currEnumMap = new EnumMap<Light,String>(Light.class);
        currEnumMap.put(Light.RED, "红色");
        currEnumMap.put(Light.GREEN, "绿色");
        currEnumMap.put(Light.YELLOW, "黄色");
        Set<Light> set = currEnumMap.keySet();
        for(Light aLight:set)
        {
            System.out.println(aLight.name()+" "+aLight.ordinal()+" "+aLight);
        }
    }

    public static void testEnumSet()
    {
        EnumSet<Light> currEnumSet = EnumSet.allOf(Light.class);
        for(Light aLightSetElement : currEnumSet)
        {
            System.out.println(aLightSetElement);
        }
    }

    public static void main(String[] args)
    {
        testTraversalEnum();
        testEnumMap();
        testEnumSet();
    }
}

运行结果:(略)
(14) 使用enum的职责链(Chain of Responsibility) .这个关系到设计模式的职责链模式。以多种不同的方法来解决一个问题。然后将他们链接在一起。当一个请求到来时,遍历这个链,直到链中的某个解决方案能够处理该请求。

时间: 2024-12-02 17:02:01

Java枚举类型enum的相关文章

全面解读Java中的枚举类型enum的使用_java

关于枚举大多数地方写的枚举都是给一个枚举然后例子就开始switch,可是我想说,我代码里头来源的数据不太可能就是枚举,通常是字符串或数字,比如一个SQL我解析后首先判定SQL类型,通过截取SQL的token,截取出来可能是SELECT.DELETE.UPDATE.INSERT.ALTER等等,但是都是字符串,此时我想用枚举就不行了,我要将字符串转换成枚举怎么转呢,类似的情况还有从数据库取出数据根据一些类型做判定,从页面传入数据,根据不同的类型做不同的操作,但是都是字符串,不是枚举,悲剧的是我很少

高阶Java-Java枚举类型enum应用详解

java的Enum枚举类型终于在j2se1.5出现了.之前觉得它只不过是鸡肋而已,可有可无.毕竟这么多年来,没有它,大家不都过得很好吗?今日看<Thinking in Java>4th edition,里面有一句话"有时恰恰因为它,你才能够"优雅而干净"地解决问题.优雅与清晰很重要,正式它们区别了成功的解决方案与失败的解决方案.而失败的解决方案就是因为其他人无法理他."使用Enum枚举类型,可以将以前笨拙的代码变得优雅简单?但是,我同时也在思考另外一个问

C/C++中枚举类型(enum)

如果一个变量你需要几种可能存在的值,那么就可以被定义成为枚举类型.之所以叫枚举就是说将变量或者叫对象可能存在的情况也可以说是可能的值一一例举出来. 举个例子来说明一吧,为了让大家更明白一点,比如一个铅笔盒中有一支笔,但在没有打开之前你并不知道它是什么笔,可能是铅笔也可能是钢笔,这里有两种可能,那么你就可以定义一个枚举类型来表示它! enum box{pencil,pen};//这里你就定义了一个枚举类型的变量叫box,这个枚举变量内含有两个元素也称枚举元素在这里是pencil和pen,分别表示铅

Java枚举类enum介绍_java

枚举类enum是JDK1.5引入的,之前都是用public static final int enum_value来代替枚举类的.枚举类enum是一种特殊的类,它默认继承了类java.lang.Enum.和其它普通类一样,enum同样可以有成员变量.方法.构造器,也可以实现一个或多个接口,区别是: 1.如果有构造器,必须用private修饰. 2.枚举类不能派生子类. 3.枚举类所有的实例必须在第一行显示定义.系统会自动给这些实例加上public static final修饰,无须程序员显示定义

JAVA枚举类型

枚举类型用于声明一组命名的常数,当一个变量有几种可能的取值时,可以将它定义为枚举类型. 以一周为例,我们都知道一周七天且固定不变,那么我们可以使用枚举类型来表示其中的某一天. /** * 枚举类型 * * @author jianggujin * */ public enum WeekEnum { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } 这样我们定义了一个最简单的枚举类型,通过示例我么可以发现,枚举类型需要

枚举类型enum

enum枚举类型:在实际问题中,有些变量的取值被限定在一个有限的范围内.例如,一个星期内只有七天,一年只有十二个月,一个班每周有六门课程等等.如果把这些量说明为整型,字符型或其它类型显然是不妥当的.为此,C语言提供了一种称为"枚举"的类型.在"枚举"类型的定义中列举出所有可能的取值,被说明为该"枚举"类型的变量取值不能超过定义的范围.应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型. enum是枚举型

C#语法学习:枚举类型(Enum)

/*枚舉 * 當你想讓一組數字代表特定的意義,並且希望是安全的,可讀性強. * * 枚舉類型是以"自己的方式使用整型" * 枚舉類型可以是:byte,sbyte,short,ushort,int,uint,long,ulong的子類 * 如果沒有指定類型,則默認為int類型 * * 枚舉類型的大小是所有元索的大小的總和 * */ using System; class Test { //enum Color{Red,Gree,Blue} //enum Color{Red=6,Gree=

【Java】Java枚举类型示例

package com.ceac.deng; public class T13Enum { public static void main(String[] args) { // TODO Auto-generated method stub WeekDay todDay = WeekDay.SAT; System.out.println(todDay + "的下一天是" + todDay.nextDay()); } } class WeekDay { public final sta

Java 语言中 Enum 类型的使用介绍

Enum 类型的介绍 枚举类型(Enumerated Type) 很早就出现在编程语言中,它被用来将一组类似 的值包含到一种类型当中.而这种枚举类型的名称则会被定义成独一无二的类型描述符,在这一点上和常量的 定义相似.不过相比较常量类型,枚举类型可以为申明的变量提供更大的取值范围. 举个例子来说明 一下,如果希望为彩虹描绘出七种颜色,你可以在 Java 程序中通过常量定义方式来实现. 清单 1. 常量定义 Public static class RainbowColor { // 红橙黄绿青蓝紫