`

Java新特性之Enum详解(二)

 
阅读更多

1.枚举元素列表必须写在枚举类的最前面,每个元素之间用逗号隔开,元素列表结束位置后若没有其他内容,则可以不写分号,否则必须要写。
2.枚举类中所有的构造器是private的,外部程序不能够创建枚举类的实例。枚举类中可以显式的指明调用哪个构建器,如MEMBER和 MEMBER()这两种元素列表声明是等价的,都是调用默认的构建器,
    而MEMBER("普通会员")则是显式的指明程序调用第二个构建器.
       (1) 构造器只是在构造枚举值的时候被调用。
       (2) 构造器只能私有private,绝对不允许有public构造器。这样可以保证外部代码无法新构造枚举类的实例。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。
       而且这个私有修饰符是由编译器自动加的,如果我们定义这些构造函数时,在前面加上public 修饰符, 就会导致编译错误, 但枚举类的方法和数据域可以允许外部访问。
       (3) 枚举类型里定义的每一个值都是枚举类型的一个实例,缺省时都将映射到Enum(String name, int ordinal) 构造函数中.枚举类型可以使用参数为定义一些自己的构造函数。      
3.枚举类可以有抽象方法,但必须在元素列表声明中实现这些方法。此外,枚举类中还可以声明一些普通的成员变量和方法,如上例所示。
枚举类中常见方法
    1).toString()方法,显示枚举类元素,上例中对这个方法进行了覆盖,如果不覆盖它的话一般打印变量名,上例中为"MEMBER","ADMIN","SUPERADMIN";
    2).valueOf(String arg0)方法,通过传入的arg0字符串解析出一个该枚举类的实例,其中传入的字符串必须是元素列表的名称之一,否则将抛出 java.lang.IllegalArgumentException异常,
    在web应用中这个方法作用很重要。该方法为静态方法,不需创建实例即可使用,如通过EnumAccessControll.valueOf("MEMBER")即可返回Member实例.
    3).values()方法,返回一个该枚举类的数组,其中数组的元素即为该枚举类中元素列表中的元素。
    4).ordinal()方法,返回枚举元素实例中元素列表中的位置,起始位置为0。如 EnumAccessControll.SUPERADMIN.ordinal()的结果为2。
    5).compareTo()方法,比较两个元素。
    6).getDeclaringClass()返回与此枚举常量的枚举类型对应的Class对象。
    7).name()方法,默认情况下返回元素实列的变量名,该方法为final不可覆盖的.

注意事项:
    1:所有创建的枚举类型都扩展于 java.lang.Enum. Enum 是在J2SE 5.0 里定义的一个新类,它本身不是枚举类型.在创建枚举类型时,必须用enum 关键字,不能直接地定义一个继承Enum的类来创建一
    个枚举类型,尽管所有创建的枚举类型实际上都是Enum 的子类.
    2:枚举类型里定义的每一个值都是枚举类型的一个实例,缺省时都将映射到Enum(String name, int ordinal) 构造函数中.枚举类型可以使用参数为定义一些自己的构造函数。
    另外要强调的两点:
        1)一是这些枚举类型的构造函数都是私有的.它是不能被其它的类或者其它的枚举类型调用的. 而且这个私有修饰符是由编译器自动加的,如果我们定义这些构造函数时,在前面加上public 修饰符,
        就会导致编译错误,
        2)二是变量定义必须在枚举类型值定义之后
    3:枚举类型每一个值都是public, static and final的.也就是说,这些值是唯一的而且一旦定义了是不能被重写或修改.而且尽管在枚举类型每一个值声明时没有出现static关键字,实际上值都是静态的,
     而且我们不能在值前面加上static, public,final 修饰符
    4:switch语句里使用枚举类型时,一定不能在每一个枚举类型值的前面加上枚举类型的类名(case后面的值),否则编译器就会报错
    5:在J2SE 5.0 的java.util 程序包中提供两个新类:EnumMap 和 EnumSet,这两个类与枚举类型的结合应用可使以前非常繁琐的程序变得简单方便.EnumMap 类提供了java.util.Map 接口的一个特殊实现,
    该接口中的键(key)是一个枚举类型
    6:特定于常量的类主体 :
      提到枚举类型可以定义自己的函数,其实更进一步,枚举类型的每一个值都可以实现枚举类型里定义的抽象函数
枚举中添加新方法

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的方法
 覆盖toString()方法,给我们提供了另外一种方式莱维枚举实例生成不同的字符串描述信息。下面的示例,我们使用的就是实例的名字,不过我们希望改变其格式,覆盖enum的
 toString的方法与覆盖一般类的方法没有区别;

public enum SpaceShip {
    SCOUT,CARGO,TRANSPORT,CRUISER,BATTLESHIP,MOTHERSHIP;
    public String toString(){
        String id= name();
        String lower=id.substring(1).toLowerCase();
        return id.charAt(0)+lower;
    }
    public static void main(String[] args){

    }
}
run:
Scout
Cargo
Transport
Cruiser
Battleship
Mothership

 values()  VS   getEnumConstants()
   由于values方法时由编译器插入到enum定义中的static方法,所以,如果你将enum实例向上转型为Enum,那么values()方法就不可以访问了,不过在Class中有一个getEnmuConstants()
  方法,所以即便Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有的enum实例:

enum Search { HITHER,YOU}
public class UpcastEnum {
    public static void main(String[] args){
        Search[] vals= Search.values();
        Enum e= Search.HITHER;
        for(Enum en: e.getClass().getEnumConstants())
            System.out.println(en);
    }

}
run:
HITHER
YOU

 PS:因为getEnmuConstants()是Class上的方法,所以你甚至可以对布什枚举的类调用此方法,值不过,此时该方法返回null,所以当你试图使用其返回的结果时会发生异常。

Enum的实现而非继承
   我们已经知道,所有的enum都继承自Java。lang.Enum类,由于java不支持多重继承,所以你的enum 不能在继承其他的类

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics