Enum
一般用来表示一组相同类型的常量.比如性别,月份,颜色等.
1.声名Enum
Public enum Sex{
MAN,
WOMAN
}
Public enum Color{
RED,BLUE,GREEN,BLACK
}
2. 使用Enum
JavaEnum简单的用法一般用于代表一组常量,可用来代码一类相同类型的常量值.[常量一般大写,注意规范]
package org.yclframework.auth.test.dao.ibatis;
public enum Sex {
MAN("男"),WOMAN("女");
private final String sex;
private Sex(String sex){
this.sex=sex;
}
public String getSex(){
return sex;
}
public static void print(String sex){
if(sex.equals("MAN")){
System.out.println(Sex.MAN.getSex());
}else if(sex.equals("WOMAN")){
System.out.println(Sex.WOMAN.getSex());
}
}
}
建立测试类如下:
package org.yclframework.auth.test.dao.ibatis;
public class Testenum {
/**
* @param args
*/
public static void main(String[] args) {
for(Sex sex:Sex.values()){
System.out.println(sex.getSex());
}
Sex.print("MAN");
}
}
这个Enum类到底和正常的类有何区别,请看以下分解:
// Compiled from Sex.java (version 1.5 : 49.0, super bit)
// Signature: Ljava/lang/Enum<Lorg/yclframework/auth/test/dao/ibatis/Sex;>;
public final enum org.yclframework.auth.test.dao.ibatis.Sex {
//enum是最终类,不可改变的.
// Field descriptor #6 Lorg/yclframework/auth/test/dao/ibatis/Sex;
public static final enum org.yclframework.auth.test.dao.ibatis.Sex MAN;//声名自身变量
// Field descriptor #6 Lorg/yclframework/auth/test/dao/ibatis/Sex;
public static final enum org.yclframework.auth.test.dao.ibatis.Sex WOMAN;//声名自身变量
// Field descriptor #9 Ljava/lang/String;
private final java.lang.String sex;//声名一个string类型
// Field descriptor #11 [Lorg/yclframework/auth/test/dao/ibatis/Sex;
private static final synthetic org.yclframework.auth.test.dao.ibatis.Sex[] ENUM$VALUES;//声名一个数组
// Method descriptor #13 ()V
// Stack: 5, Locals: 0
static {};
0 new org.yclframework.auth.test.dao.ibatis.Sex [1]//创建一个sex对象
3 dup制栈顶数值并将复制值压入栈顶
4 ldc <String "MAN"> [15] 将String型常量值从常量池中推送至栈顶
6 iconst_0 将int型0推送至栈顶
7 ldc <String "男"> [16] 将String型常量值从常量池中推送至栈顶
9 invokespecial org.yclframework.auth.test.dao.ibatis.Sex(java.lang.String, int, java.lang.String) [18]调用Sext的方法,这个方法参数为String ,int,String
12 putstatic org.yclframework.auth.test.dao.ibatis.Sex.MAN : org.yclframework.auth.test.dao.ibatis.Sex [22]
为指定的类的静态域赋值
15 new org.yclframework.auth.test.dao.ibatis.Sex [1]
18 dup
19 ldc <String "WOMAN"> [24]
21 iconst_1
22 ldc <String "女"> [25]
24 invokespecial org.yclframework.auth.test.dao.ibatis.Sex(java.lang.String, int, java.lang.String) [18]
27 putstatic org.yclframework.auth.test.dao.ibatis.Sex.WOMAN : org.yclframework.auth.test.dao.ibatis.Sex [27]
30 iconst_2
31 anewarray org.yclframework.auth.test.dao.ibatis.Sex [1]
34 dup
35 iconst_0
36 getstatic org.yclframework.auth.test.dao.ibatis.Sex.MAN : org.yclframework.auth.test.dao.ibatis.Sex [22]
获取指定类的静态域,并将其值压入栈顶
39 aastore
40 dup
41 iconst_1
42 getstatic org.yclframework.auth.test.dao.ibatis.Sex.WOMAN : org.yclframework.auth.test.dao.ibatis.Sex [27]
45 aastore
46 putstatic org.yclframework.auth.test.dao.ibatis.Sex.ENUM$VALUES : org.yclframework.auth.test.dao.ibatis.Sex[] [29]
49 return
Line numbers:
[pc: 0, line: 4]
[pc: 30, line: 3]
// Method descriptor #21 (Ljava/lang/String;ILjava/lang/String;)V
// Stack: 3, Locals: 4
private Sex(java.lang.String arg0, int arg1, java.lang.String sex);
0 aload_0 [this]
1 aload_1
2 iload_2
3 invokespecial java.lang.Enum(java.lang.String int,) [33]
6 aload_0 [this]
7 aload_3 [sex]
8 putfield org.yclframework.auth.test.dao.ibatis.Sex.sex : java.lang.String [36]
11 return
Line numbers:
[pc: 0, line: 8]
[pc: 6, line: 9]
[pc: 11, line: 10]
Local variable table:
[pc: 0, pc: 12] local: this index: 0 type: org.yclframework.auth.test.dao.ibatis.Sex
[pc: 0, pc: 12] local: sex index: 3 type: java.lang.String
// Method descriptor #40 ()Ljava/lang/String;
// Stack: 1, Locals: 1
public java.lang.String getSex();
0 aload_0 [this]
1 getfield org.yclframework.auth.test.dao.ibatis.Sex.sex : java.lang.String [36]
4 areturn
Line numbers:
[pc: 0, line: 13]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: org.yclframework.auth.test.dao.ibatis.Sex
// Method descriptor #42 (Ljava/lang/String;)V
// Stack: 2, Locals: 1
public static void print(java.lang.String sex);
0 aload_0 [sex]
1 ldc <String "MAN"> [15]
3 invokevirtual java.lang.String.equals(java.lang.Object) : boolean [43]
6 ifeq 24
9 getstatic java.lang.System.out : java.io.PrintStream [49]
12 getstatic org.yclframework.auth.test.dao.ibatis.Sex.MAN : org.yclframework.auth.test.dao.ibatis.Sex [22]
15 invokevirtual org.yclframework.auth.test.dao.ibatis.Sex.getSex() : java.lang.String [55]
18 invokevirtual java.io.PrintStream.println(java.lang.String) : void [57]
21 goto 45
24 aload_0 [sex]
25 ldc <String "WOMAN"> [24]
27 invokevirtual java.lang.String.equals(java.lang.Object) : boolean [43]
30 ifeq 45
33 getstatic java.lang.System.out : java.io.PrintStream [49]
36 getstatic org.yclframework.auth.test.dao.ibatis.Sex.WOMAN : org.yclframework.auth.test.dao.ibatis.Sex [27]
39 invokevirtual org.yclframework.auth.test.dao.ibatis.Sex.getSex() : java.lang.String [55]
42 invokevirtual java.io.PrintStream.println(java.lang.String) : void [57]
45 return
Line numbers:
[pc: 0, line: 17]
[pc: 9, line: 18]
[pc: 24, line: 19]
[pc: 33, line: 20]
[pc: 45, line: 23]
Local variable table:
[pc: 0, pc: 46] local: sex index: 0 type: java.lang.String
// Method descriptor #63 ()[Lorg/yclframework/auth/test/dao/ibatis/Sex;
// Stack: 5, Locals: 3
public static org.yclframework.auth.test.dao.ibatis.Sex[] values();//声名values数组
0 getstatic org.yclframework.auth.test.dao.ibatis.Sex.ENUM$VALUES : org.yclframework.auth.test.dao.ibatis.Sex[] [29]
3 dup
4 astore_0
5 iconst_0
6 aload_0
7 arraylength
8 dup
9 istore_1
10 anewarray org.yclframework.auth.test.dao.ibatis.Sex [1]
13 dup
14 astore_2
15 iconst_0
16 iload_1
17 invokestatic java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int) : void [64]
20 aload_2
21 areturn
Line numbers:
[pc: 0, line: 1]
// Method descriptor #69 (Ljava/lang/String;)Lorg/yclframework/auth/test/dao/ibatis/Sex;
// Stack: 2, Locals: 1
public static org.yclframework.auth.test.dao.ibatis.Sex valueOf(java.lang.String arg0);
0 ldc <Class org.yclframework.auth.test.dao.ibatis.Sex> [1]
2 aload_0
3 invokestatic java.lang.Enum.valueOf(java.lang.Class, java.lang.String) : java.lang.Enum [70]
6 checkcast org.yclframework.auth.test.dao.ibatis.Sex [1]
9 areturn
Line numbers:
[pc: 0, line: 1]
}
看这个Sex类,我明明很简单的几个方法,为什么会有这么多的解析过程:
private static final synthetic org.yclframework.auth.test.dao.ibatis.Sex[] ENUM$VALUES;//声名一个数组
MAN("男")既然解析成:
new org.yclframework.auth.test.dao.ibatis.Sex [1]//创建一个sex对象
dup制栈顶数值并将复制值压入栈顶
ldc <String "MAN"> [15] 将String型常量值从常量池中推送至栈顶
iconst_0 将int型0推送至栈顶
ldc <String "男"> [16] 将String型常量值从常量池中推送至栈顶
invokespecial org.yclframework.auth.test.dao.ibatis.Sex(java.lang.String, int, java.lang.String) [18]调用Sex的方法,这个方法参数为String ,int,String
putstatic org.yclframework.auth.test.dao.ibatis.Sex.MAN : org.yclframework.auth.test.dao.ibatis.Sex [22]
为指定的类的静态域赋值
JVM自动将MAN("男")解析为字符串”MAN”,int下标 0,字符串”男”,再自动invoke Sex(String,int,String)Sex(“MAN”,0,”男”);
然后在后面又声名了一个数组,并把他们添加进去.
31 anewarray org.yclframework.auth.test.dao.ibatis.Sex [1]
34 dup
35 iconst_0
36 getstatic org.yclframework.auth.test.dao.ibatis.Sex.MAN : org.yclframework.auth.test.dao.ibatis.Sex [22]
获取指定类的静态域,并将其值压入栈顶
39 aastore
40 dup
41 iconst_1
42 getstatic org.yclframework.auth.test.dao.ibatis.Sex.WOMAN : org.yclframework.auth.test.dao.ibatis.Sex [27]
45 aastore
46 putstatic org.yclframework.auth.test.dao.ibatis.Sex.ENUM$VALUES : org.yclframework.auth.test.dao.ibatis.Sex[] [29]
49 return
在类的最后又添加了一个变量,名为values(),并有一个方法把上面的数组复制过来
public static org.yclframework.auth.test.dao.ibatis.Sex[] values();//声名values数组
invokestatic java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int) : void [64]
public static org.yclframework.auth.test.dao.ibatis.Sex valueOf(java.lang.String arg0);
这些方法是后来添加的,因为这个类用了很多的static final 不可改变的固定地址,JVM调用的时候用比较快。让我们反编译这个类来看看固定实现.
// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space
// Source File Name: Sex.java
package org.yclframework.auth.test.dao.ibatis;
import java.io.PrintStream;
public final class Sex extends Enum
{
public static final Sex MAN;
public static final Sex WOMAN;
private final String sex;
private static final Sex ENUM$VALUES[];
private Sex(String s, int i, String sex)
{
super(s, i);
this.sex = sex;
}
public String getSex()
{
return sex;
}
public static void print(String sex)
{
if (sex.equals("MAN"))
System.out.println(MAN.getSex());
else
if (sex.equals("WOMAN"))
System.out.println(WOMAN.getSex());
}
public static Sex[] values()
{
Sex asex[];
int i;
Sex asex1[];
System.arraycopy(asex = ENUM$VALUES, 0, asex1 = new Sex[i = asex.length], 0, i);
return asex1;
}
public static Sex valueOf(String s)
{
return (Sex)Enum.valueOf(org/yclframework/auth/test/dao/ibatis/Sex, s);
}
static
{
MAN = new Sex("MAN", 0, "男");
WOMAN = new Sex("WOMAN", 1, "女");
ENUM$VALUES = (new Sex[] {
MAN, WOMAN
});
}
}
一看代码就清楚了,原来这个类继承了enum,并调用父菜单,而我们可以直接声名为enum类型,添加了源代码,实现的功能却很丰富,这就是JDK5的魅力。
如果你把这个类用javac进行编译,对不起通不过。
Enum类不支持显示继承.