枚举类 深入浅出

我哥们写的,先贴过来了,hoho

 

 

枚举类 深入浅出

作者:曹祺
Blog: http://blogs.sun.com/greysh
Web: http://www.greysh.com
Email: Qi.Cao@Sun.com
本文链接:
http://developers.sun.com.cn/blog/functionalca/entry/%E6%9E%9A%E4%B8%BE%E7%B1%BB_%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BA
难度:初级

枚举类为Java5新加特性,本文用jad反编译解释枚举类的实质。

1.HelloWorld
2.枚举类映射


1.枚举类主要用来标示常量,尽管通常也可以把常量定义在interface或者专门的java类中,但是定义在枚举类中更方便,在Java 5以及其后的

版本,采用enmu申明的类即是枚举类
例如
public enum EnumDemo {}
其等价于
public final class EnumDemoMethod extends Enum{}//反编译结果
Enum为java.lang包的一个子类,因为继承自父类,因此可以override其父类方法。
采用final关键词,所以不能被子类继承(本身就是用来标示常量,所以也没必要)

例如声明一个类
public enum EnumDemo {
   STUDENTS,TEACHER;
}
我们在调用的时候,其实相当于(当然,枚举类的索引是可以重新赋值的)
STUDENTS=0
TEACHER=1
我们用JAD反编译后可以看到其源代码为
public final class EnumDemo extends Enum{
   public static EnumDemo[] values(){
        return (EnumDemo[])$VALUES.clone();
    }

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

    private EnumDemo(String s, int i){
        super(s, i);
    }

    public static final EnumDemo STUDENTS;
   
public static final EnumDemo TEACHER;
   
private static final EnumDemo $VALUES[];

    static{
       
STUDENTS = new EnumDemo("STUDENTS", 0);
     
 TEACHER = new EnumDemo("TEACHER", 1);
     
  $VALUES = (new EnumDemo[] {
       STUDENTS, TEACHER
        });
    }
}

 

 

因为继承自Enum类,我们可以查看Enum的源代码,构造函数为
  protected Enum(String name, int ordinal) {
 this.name = name;
 this.ordinal = ordinal;
    }
以下是来自JDK的注释
     * @param name - The name of this enum constant, which is the identifier
     *               used to declare it.
     * @param ordinal - The ordinal of this enumeration constant (its position
     *         in the enum declaration, where the initial constant is assigned
     *         an ordinal of zero).
这样就完成了两个EnumDemo类,并且每个EnumDemo类中放置一个成员变量,而$VALUE数组则放置了这两个EnumDemo类
在运行
  return (EnumDemo)Enum.valueOf(EnumDemo, s);
进行键值对查找,实质是Enum的
ublic static <T extends Enum<T>> T valueOf(Class<T> enumType,String name)方法,
然后在 T result = enumType.enumConstantDirectory().get(name)是来自最高父类Object
的Map<String, T> enumConstantDirectory()
然后在Object的以下方法完成键值对
  T[] universe = getEnumConstantsShared();
不存在则创建MAP
Map<String, T> m = new HashMap<String, T>(2 * universe.length);
然后跟MAP赋值
for (T constant : universe)
  m.put(((Enum)constant).name(), constant);
  enumConstantDirectory = m;
因而enmu的实质是String和int构成的键值对
虽然 public static EnumDemo valueOf(String s)返回的是EnumDemo
但是我们可以把STUDENTS看成索引0元素,把TEACHER看成索引1元素也是因为上述原因
另外从反编译中可以看出是继承Enum的类
因而我们可以在里面加入方法,加入一个测试方法,
整体代码变为
public enum EnumDemoMethod {
 STUDENTS,TEACHER;
 public static void main(String [] args){
  System.out.println(STUDENTS.TEACHER.STUDENTS);
 }
}

也许System.out.println(STUDENTS.TEACHER.STUDENTS)看起来很奇怪,然而我们重新发编译后,发现枚举类仅仅只增加另一个
 public static void main(String [] args){
  System.out.println(STUDENTS.TEACHER.STUDENTS);
 }
一个方法,其他代码同
public final class EnumDemo extends Enum
之所以这样,我们看反编译后的代码可以看到
public enum EnumDemoMethod {
    public static final EnumDemoMethod STUDENTS;
    public static final EnumDemoMethod TEACHER;
 //其他代码省略
}
System.out.println(STUDENTS.TEACHER.STUDENTS)等价于
System.out.println(STUDENTS);
毕竟是同一个类
枚举类作为一个类,在方法处理上我们可以从反编译代码看到并没有特比特殊的地方。


2.枚举类映射
对于学校的情况,我们考虑一种特殊的情况,仅仅只有学生和老师,我们可以设定一个bool数值,
比如用true代表学生,用false代表老师。
对于数据库映射,这种bool映射,对于常用的ORM,比如hibernate,是用短整形tinyint(1)映射bool,
然而mysql是提供enmu的类型的,我们可以制定mysql的enmu类型,然后"STUDENT","TEACHER",
枚举类型和bool映射区别在于bool只有true和false两个枚举值,而实质上可以存在很多键值对,比如
国家和语言的映射就是很多键值对。
在EJB中,如果制定ORM映射采用枚举类型,那么有两种策略
还是上述例子,
第一种映射是java中操作采用STUDENTS,TEACHER这种枚举字符串,第二种采用索引,比如STUDENTS在数据库中
储存所以0,teacher储存索引1
个人推荐后者,因为采用所以对数据库的性能和跨平台有好处。
当然,我们一般存数据库的字符串和显示的字符串是<中文字符,中文字符>的HASHMAP,而其locale如果是zh-CN,一般存中文。
对于这种情况,不太合适用enmu,存英文还好,如果强制存中文,可以
public enum EnumDemo {
学生,教师;
}
因为java是UTF编码,所以可以把中文当变量,这样可以满足需要,但是却违法java编程习惯,不推荐使用

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值