java枚举详解

简介

枚举(enum)类型是java5新增的特性,是一中新的类型。在java编程思想中是这么介绍的:关键字enum可以将一组具名的值的有限集合创建为一中新的类型。
简单的说枚举可以方便的用来定义一组常量集。在jdk1.5之前定义常量都是:

public class Color{
    public static final RED = 0;
    public static final GREEN = 1;
    public static final BLANK = 2;
    public static final YELLOW = 3;
}

而有了枚举以后,可以这样:

public enum Color{
    RED,GREEN,BLACK,YELLOW
}

创建enum的时候,编译器会为你生成一个相关的类,这个类继承自java.lang.Enum。所以enum是不能继承的。

下面代码展示了Enum提供的一些方法

package test;


enum Shrubbery{
    GROUND,
    CRAWLING,
    HANGING
}

public class EnumClass {

    public static void main(String[] args) {
        for (Shrubbery s : Shrubbery.values()){
            System.out.println(s + "ordinal:" + s.ordinal());
            System.out.println("compareTo Shrubbery.CRAWLING:" + s.compareTo(Shrubbery.CRAWLING));
            System.out.println("equals():" + s.equals(Shrubbery.CRAWLING));
            System.out.println("==:" + (s == Shrubbery.CRAWLING));
            System.out.println(s.getDeclaringClass());
            System.out.println(s.name());
            System.out.println("-------------------------------");
        }

        for (String s : "HANGING CRAWLING GROUND".split(" ")){
            Shrubbery shrub = Enum.valueOf(Shrubbery.class, s);
            System.out.println(shrub);
        }
    }
}
//输出:
GROUNDordinal:0
compareTo Shrubbery.CRAWLING:-1
equals():false
==:false
class test.Shrubbery
GROUND
-------------------------------
CRAWLINGordinal:1
compareTo Shrubbery.CRAWLING:0
equals():true
==:true
class test.Shrubbery
CRAWLING
-------------------------------
HANGINGordinal:2
compareTo Shrubbery.CRAWLING:1
equals():false
==:false
class test.Shrubbery
HANGING
-------------------------------
HANGING
CRAWLING
GROUND

ordinal()方法返回一个int值,这是每个enum实例在声明时的次序,从0开始。可以使用==来比较enum实例,编译器会自动为你提供equals()和hashCode()方法。Enum类实现了Comparable接口,所以具有compareTo()方法。getDirclaringClass()方法,我们就能知道其所属的enum类。name()方法返回enum实例声明时的名字,与toString()方法效果相同。valueOf是在Enum中定义的static方法,根据给定的名字返回相应的enum实例,如果不存在给定名字的实例,将会抛出异常。

使用

枚举有七种常见的用法

1.常量

就是我们一开始给出简单例子,可以定义一组常量集。

2.switch

JDK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。

enum Color{
    GREEN,
    BLUE,
    YELLOW
}

public class ColorClass {

    public static void main(String[] args) {
        Color color = Color.GREEN;
        switch (color){
            case BLUE:
                System.out.println("color is blue");
                break;
            case GREEN:
                System.out.println("color is green");
                break;
            case YELLOW:
                System.out.println("color is yellow");
                break;
        }
    }
}

不过有一点需要注意,在jdk1.7中switch语句可以支持String类型的参数,实际上,这个新特性是在编译器这个层次上实现的。而在 Java 虚拟机和字节代码这个层次上,还是只支持在 switch 语句中使用与整数类型兼容的类型。

3.向枚举中添加新方法
public enum OzWitch {

    WEST("west"),
    NORTH("north"),
    EAST("east"),
    SOUTH("south");

    private String description;

    private OzWitch(String description){
        this.description = description;
    }

    public String getDescription(){
        return description;
    }

    public static void main(String[] args) {
        for (OzWitch witch : OzWitch.values())
            System.out.println(witch + ":" + witch.getDescription());
    }
}

我们可以向enum中添加方法,包括main()方法。需要注意的是:如果打算定义自己的方法,那么必须在enum实例序列的最后添加一个分号。同时,java要求必须先定义enum实例,否则报错。

4.覆盖enum方法

enum可以覆盖toString()方法。

enum Color{
    GREEN,
    BLUE,
    YELLOW;

    @Override
    public String toString() {
        String id = name();
        String lower = id.substring(1).toLowerCase();
        return id.charAt(0) + lower;
    }
}

public class ColorClass {

    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c);
        }
    }
}
5.实现接口
public interface Behaviour {  
    void print();  
    String getInfo();  
}  
public enum Color implements Behaviour{  
    RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);  
    // 成员变量  
    private String name;  
    private int index;  
    // 构造方法  
    private Color(String name, int index) {  
        this.name = name;  
        this.index = index;  
    }  
    //接口方法  
    @Override  
    public String getInfo() {  
        return this.name;  
    }  
    //接口方法  
    @Override  
    public void print() {  
        System.out.println(this.index+":"+this.name);  
    }  
}  

所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。

6.使用接口组织枚举

因为enum无法继承但我们又想通过使用积累将一个enum中的元素进行分组。这时我们可以在一个接口的内部,创建实现该接口的枚举,以此将元素进行分组,可以达到将枚举元素分类组织的目的。

public interface Food{
        enum Appetizer implements Food{
            SALAD, SOUP, SPRING_ROLLS;
        }
        enum MainCourse implements Food{
            LASAGNE, BURRITO, PAD_THAI,
            LENTILS, HUMMOUS, VINDALOO;
        }
        enum Dessert implements Food{
            TIRAMISU, GELATO, BLACK_FOREST_CAKE,
            FRUIT, CREME_CARAMEL;
        }
        enum Coffee implements Food{
            BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
            LATTE, CAPUCCINO, TEA, HERB_TEA;
        }
    }
7.EnumSet和EnumMap

java.util.EnumSet和java.util.EnumMap是两个枚举集合。EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,而value则可以是任意类型。关于这个两个集合的使用就不在这里赘述,可以参考JDK文档。

其他特征

java的enum有一个有趣的特征,即允许程序员为enum实例编写方法,是每个enum实例有各自不同的行为。

enum Color{
    GREEN{
        public String getInfo(){
            return "color is green";
        }
    },
    BLUE{
        public String getInfo(){
            return "color is blue";
        }
    },
    YELLOW{
        public String getInfo(){
            return "color is blue";
        }
    };

    abstract public String getInfo();
}

public class ColorClass {

    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c.getInfo());
        }
    }
}

参考资料:
《java编程思想》
http://softbeta.iteye.com/blog/1185573

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值