Java5 枚举类型使用总结

Java5 枚举类型使用总结

一、概述

枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。Tiger 专家、developerWorks 的多产作者 Brett McLaughlin 将解释枚举的定义,介绍如何在应用程序中运用枚举,以及它为什么能够让您抛弃所有旧的 public static final 代码。

枚举在什么地方适用呢?一条普遍规则是,任何使用常量的地方,例如目前用 switch 代码切换常量的地方。如果只有单独一个值(例如,鞋的最大尺寸,或者笼子中能装猴子的最大数目),则还是把这个任务留给常量吧。但是,如果定义了一组值,而这些值中的任何一个都可以用于特定的数据类型,那么将枚举用在这个地方最适合不过。

二、在枚举类型之前,Java是如何实现枚举功能的

在枚举类型出现之前,java是通过在接口或者类中定义public static final 的变量来实现的。比如,对于经典的红色警戒2中的英国狙击(sharp-shooter)手三个动作的描述:

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 8:53:04
* 狙击手活动
*/
public interface SharpShooter_1 {
    public static final int LOCKED = 1;     //锁定
    public static final int AIM = 2;        //瞄准
    public static final int SHOOT = 3;      //射击
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 9:03:50
* 测试方法
*/
public class TestDemo_1 {
    public static void main(String args[]) {
        TestDemo_1 test = new TestDemo_1();
        test.doAction(1);
        test.doAction(2);
        test.doAction(3);
        test.doAction(4);
    }

/**
     * 执行的动作
     * @param action
     */
    public void doAction(int action) {
        switch (action) {
            case SharpShooter_1.LOCKED:
                System.out.println("1:锁定目标");
                break;
            case SharpShooter_1.AIM:
                System.out.println("2:瞄准目标");
                break;
            case SharpShooter_1.SHOOT:
                System.out.println("3:射击");
                break;
            default:
                System.out.println("×:游戏还没有定义此动作!");
        }
    }
}

运行结果:

1:锁定目标
2:瞄准目标
3:射击
×:游戏还没有定义此动作!

[说明]:当然SharpShooter_1也可以声明为class,还可以直接将常量定义到TestDemo_1中,如果常量只是在类内部使用,就声明为private或者是protected,如果声明为public,则通常是与类功能相联系的常数。

[注意]:switch语句的条件只能接收数值或字符(byte、short、int或char)或枚举(enum)类型的变量名或表达式。如果没有符合条件数值或字符,则执行default语句,default语句不是必须的,如果没有默认要处理的动作,则default语句可省略。break语句的作用是跳出循环块。

三、枚举类型的等价实现

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 10:10:41
* 狙击手活动(枚举类型实现)
*/
public enum SharpShooter_2 {
    LOCKED,
    AIM,
    SHOOT
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 10:12:40
* 测试普通枚举类型
*/
public class TestDemo_2 {

public static void main(String args[]){
        TestDemo_2 test=new TestDemo_2();
        test.doAction(SharpShooter_2.LOCKED);
        test.doAction(SharpShooter_2.AIM);
        test.doAction(SharpShooter_2.SHOOT);
    }
    /**
     * 执行的动作
     * @param action
     */
    public void doAction(SharpShooter_2 action) {
        switch (action) {
            case LOCKED:
                System.out.println("1:锁定目标");
                break;
            case AIM:
                System.out.println("2:瞄准目标");
                break;
            case SHOOT:
                System.out.println("3:射击");
                break;
            default:
                System.out.println("×:游戏还没有定义此动作!");
        }
    }
}

运行结果:

1:锁定目标
2:瞄准目标
3:射击

三、枚举类型的实质

在编译SharpShooter_2.java后,会生成一个SharpShooter_2.class文件,这说明枚举类型的实质还是一个类。因此,在某种程度上,enum关键字的作用就是class或者interface。

当使用enum定义一个枚举类型时,实际上所定义的类型自动继承了java.lang.Enum类。而每个被枚举的成员实质就是一个枚举类型的实例,他们默认都是public static final的。可以直接通过枚举类型名直接使用它们。

在查询JDK1.5文档的java.lang.Enum类,里面清楚的说明:java.lang.Enum类是所有 Java 语言枚举类型的公共基本类。因此,所有枚举类型都拥有有java.lang.Enum类所提供的共有方法。因此,要学会使用枚举,还必须认识java.lang.Enum类。下面将详细说明。

四、java.lang.Enum类

public abstract class Enum<E extends Enum<E>>extends Objectimplements Comparable<E>, Serializable这是所有 Java 语言枚举类型的公共基本类。

------------------

构造方法摘要

protected Enum(String name,int ordinal)

单独的构造方法。程序员无法调用此构造方法。该构造方法用于由响应枚举类型声明的编译器发出的代码。

参数:

name - - 此枚举常量的名称,它是用来声明该常量的标识符。

ordinal - - 枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

------------------

方法摘要

protected  Object clone()

抛出 CloneNotSupportedException。

int compareTo(E o)

比较此枚举与指定对象的顺序。在该对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。 枚举常量只能与相同枚举类型的其他枚举常量进行比较。该方法实现的自然顺序就是声明常量的顺序。

boolean equals(Object other)

当指定对象等于此枚举常量时,返回 true。

Class<E> getDeclaringClass()

返回与此枚举常量的枚举类型相对应的 Class 对象。当且仅当 e1.getDeclaringClass() == e2.getDeclaringClass() 时,两个枚举常量 e1 和 e2 的枚举类型才相同。(由该方法返回的值不同于由 Object.getClass() 方法返回的值,Object.getClass() 方法用于带有特定常量的类主体的枚举常量。)

int hashCode()

返回枚举常量的哈希码。

String name()

返回此枚举常量的名称,在其枚举声明中对其进行声明。 与此方法相比,大多数程序员应该优先考虑使用 toString() 方法,因为 toString 方法返回更加用户友好的名称。该方法主要设计用于特殊情形,其正确性取决于获得正确的名称,其名称不会随版本的改变而改变

int ordinal()

返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。 大多数程序员不会使用此方法。它被设计用于复杂的基于枚举的数据结构,比如 EnumSet 和 EnumMap。

String toString()

返回枚举常量的名称,它包含在声明中。

public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)

返回带指定名称的指定枚举类型的枚举常量。名称必须与在此类型中声明枚举常量所用的标识符完全匹配。(不允许使用额外的空白字符。)

参数:

enumType - 要从中返回常量的枚举类型的 Class 对象

name - 要返回的常量名称

注意:ordinal() 方法得到枚举顺序的索引,默认从0开始。

五、枚举的高级用法

1、枚举方法

既然枚举的本质是类,那么定义枚举类型时也可以定义方法。比如:

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 11:29:23
* 带方法的枚举类型
*/
public enum SharpShooter_3 {
    LOCKED,
    AIM,
    SHOOT;

public String getDesc() {
        switch (this.ordinal()) {
            case 0:
                return "锁定目标";
            case 1:
                return "瞄准目标";
            case 2:
                return "射击";
            default:
                return "没有该枚举值!";
        }
    }
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 11:32:40
* 测试枚举方法
*/
public class TestDemo_3 {
    public static void main(String args[]) {
        for (SharpShooter_3 enumSS : SharpShooter_3.values()) {
            System.out.println(enumSS + " " + enumSS.getDesc());
        }
    }
}

运行结果:

LOCKED 锁定目标
AIM 瞄准目标
SHOOT 射击

Process finished with exit code 0

2、枚举构造方法

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 11:37:20
* 带私有构造方法的枚举类型
*/
public enum SharpShooter_4 {
    LOCKED("锁定目标"),
    AIM("瞄准目标"),
    SHOOT("射击");

private String desc;        //枚举说明

/**
     * 私有的构造方法
     */
    private SharpShooter_4(String desc){
        this.desc=desc;
    }

/**
     * 获取枚举值的说明
     * @return String
     */
    public String getDesc(){
        return desc;
    }
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 11:42:50
* 测试带私有构造方法的枚举类型
*/
public class TestDemo_4 {
    public static void main(String args[]) {
        for (SharpShooter_4 enumSS : SharpShooter_4.values()) {
            System.out.println(enumSS + " " + enumSS.getDesc());
        }
    }
}

运行结果:

LOCKED 锁定目标
AIM 瞄准目标
SHOOT 射击

Process finished with exit code 0

3、实现接口的枚举

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 13:59:47
* 说明接口
*/
public interface IDesc {
    /**
     * 获取说明信息
     * @return String
     */
    public String getDesc();
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 13:43:22
* 实现了接口的枚举类型
*/
public enum SharpShooter_5 implements IDesc {
    LOCKED("锁定目标"),
    AIM("瞄准目标"),
    SHOOT("射击");

private String desc;        //枚举说明

/**
     * 私有的构造方法
     */
    private SharpShooter_5(String desc) {
        this.desc = desc;
    }

public String getDesc() {
        return desc;
    }
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 14:03:26
* 测试实现了接口的枚举类型
*/
public class TestDemo_5 {
    public static void main(String args[]) {
        for (SharpShooter_5 enumSS : SharpShooter_5.values()) {
            System.out.println(enumSS + " " + enumSS.getDesc());
        }
    }
}

运行结果:

LOCKED 锁定目标
AIM 瞄准目标
SHOOT 射击

Process finished with exit code 0

4、每个枚举值实现的自己的接口

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 14:05:48
* 每个枚举值自己实现接口
*/
public enum SharpShooter_6 implements IDesc {
    LOCKED(){
        public String getDesc() {
            return "锁定目标";
        }
    },

AIM{
        public String getDesc() {
            return "瞄准目标";
        }
    },

SHOOT{
        public String getDesc() {
            return "射击";
        }
    }
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 14:10:28
* 测试每个枚举值自己实现接口
*/
public class TestDemo_6 {
    public static void main(String args[]) {
        for (SharpShooter_6 enumSS : SharpShooter_6.values()) {
            System.out.println(enumSS + " " + enumSS.getDesc());
        }
    }
}

运行结果:

LOCKED 锁定目标
AIM 瞄准目标
SHOOT 射击

Process finished with exit code 0

5、带有抽象方法的枚举类型

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 14:13:25
* 带有抽象方法的枚举类型
*/
public enum SharpShooter_7 {
    LOCKED(){
        public String getDesc() {
            return "锁定目标";
        }
    },

AIM{
        public String getDesc() {
            return "瞄准目标";
        }
    },

SHOOT{
        public String getDesc() {
            return "射击";
        }
    };

/**
     * 抽象方法,每个枚举值都必须自己实现
     *
     * @return String
     */
    public abstract String getDesc();
}

/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-29
* Time: 14:16:56
* 测试带有抽象方法的枚举类型
*/
public class TestDemo_7 {
    public static void main(String args[]) {
        for (SharpShooter_7 enumSS : SharpShooter_7.values()) {
            System.out.println(enumSS + " " + enumSS.getDesc());
        }
    }
}

运行结果:

LOCKED 锁定目标
AIM 瞄准目标
SHOOT 射击

Process finished with exit code 0

六、对Java枚举类型的一些看法

枚举的本质是类,在没有枚举之前,仍然可以按照java最基本的编程手段来解决需要用到枚举的地方。枚举屏蔽了枚举值的类型信息,不像在用public static final定义变量必须指定类型。枚举是用来构建常量数据结构的模板,这个模板可扩展。枚举的使用增强了程序的健壮性,比如在引用一个不存在的枚举值的时候,编译器会报错。枚举的更多用法还需要在开发中去研究创造,Java5、Java6增加了不少新的特性,技术在升级,对程序员来说就要学习,如果你热爱java的话。否则别人用到新特性的代码你看不懂,那才叫郁闷。

目前,本人在开发中也很少用到枚举,虽然Java设计得很好,处心积虑为开发人员着想,但是是否有必要增加一个关键字让全世界的java程序员去学习研究?本人感觉Java现在越来越复杂了,新特性对我而言是一大障碍,需要大量的时间去熟悉?对此,我也不敢妄下结论,一是我们和java科学家差距太大,二是怕误导读者,这个就留个各位读者吧!

原文地址:https://www.cnblogs.com/awzh2020/p/12541859.html

时间: 2024-09-30 11:30:12

Java5 枚举类型使用总结的相关文章

C#枚举类型的常用操作总结

枚举类型是定义了一组"符号名称/值"配对.枚举类型是强类型的.每个枚举类型都是从system.Enum派生,又从system.ValueType派生,而system.ValueType又从system.Object派生,所以枚举类型是指类型. 编译枚举类型时,C#编译器会把每个符号转换成类型的一个常量字段.C#编译器将枚举类型视为基元类型. 1.获取枚举列表:         /// <summary>         /// 获取枚举列表         /// <

获取枚举类型Description特性的描述信息

C#中可以对枚举类型用Description特性描述. 如果需要对Description信息获取,那么可以定义一个扩展方法来实现.代码如下: public static class EnumExtensions { public static string GetDescription(this object value) { if (value==null) return string.Empty; Type type = value.GetType(); var fieldInfo = ty

C++ Primer 笔记——枚举类型

1.和类一样,每个枚举类型定义了一种新的类型.枚举属于字面值常量类型. 2.C++包含两种枚举:限定作用域的和不限定作用域的.C++11新标准引入了限定作用域的枚举类型. enum class /*struct*/ MyEnum { A = 0}; // 限定作用域的枚举 enum class /*struct*/ MyEnum1 { A = 0 }; // 限定作用域的枚举可以有重复的名字,使用时也必须加上作用域 enum MyEnum2 { B = 0 }; // 不限定作用域的枚举 enu

笔记:枚举类型

枚举类型的定义格式如: public enum Size{ SMALL,MEDIUM,LARGE,EXTRA_LARGE} ? ? 实际上,这个声明定义了一个类 size,该类是一个特殊的类,可以定义自己的数据字段.方法.可以实现接口,也可以定义自己的构造器.但枚举类使用 enum 定义后在编译后默认继承了 java.lang.Enum 类,而不是普通的继承 Object类.Enum 声明类继承了 Serializable 和 Comparable 两个接口.且采用 enum 声明后,该类会被编

结构体 枚举类型

结构体 class Program { struct student { public int num; public string name; public string sex; public one oone; public int[] qq; } struct one { public string aa; public int bb; } static void Main(string[] args) { ////struct ////初始化结构体 //student stu = ne

C#之枚举类型

参考: http://www.cnblogs.com/an-wl/archive/2011/04/14/2015815.html 惯例先上MSDN: https://msdn.microsoft.com/zh-cn/library/cc138362(v=vs.110).aspx 枚举类型(也称为枚举)为定义一组可以赋给变量的命名整数常量提供了一种有效的方法.例如,假设您必须定义一个变量,该变量的值表示一周中的一天.该变量只能存储七个有意义的值.若要定义这些值,可以使用枚举类型.枚举类型是使用en

利用枚举类型实现统计

口袋中有5种颜色的小球,每次从口袋中任意取3个,问得到3种不同颜色的小球的可能取法? #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream> #include<iomanip> using namespace std; int main() { enum color{red,yellow,blue,white,black};//声明枚举类型color color pri;    //定义color类型的变量pri int i, j,

WebService中使用枚举类型

1.在服务端编写枚举值 public enum BackWorkType { None, Test } 2.为每一个枚举值添加下面属性,添加下面属性后服务可以通过对象字符串进行序列化 [EnumMember(Value = "None")] 3.添加完后枚举变成 public enum BackWorkType { [EnumMember(Value = "None")] None, [EnumMember(Value = "Test")] Te

C# 获取与解析枚举类型的 DescriptionAttribute

原文:C# 获取与解析枚举类型的 DescriptionAttribute System.ComponentModel.DescriptionAttribute 这个 Attribute,经常被用来为属性或事件提供说明,这个说明是可以被本地化的.在一些用户界面中,就可以利用这个 Attribute 提供一些额外的信息,就像 Visual Studio 中所做的,如图 1 所示: 图 1 可以看到,对 AutoSizeMode 的说明,被显示在了下面的框中. 但是,界面中的枚举项就没这么好的待遇了