- 什么是枚举?
- 为什么要用枚举?
- 枚举可以怎么用?
- Pros VS Cons
1.什么是枚举
首先我们从一个枚举类的反编译文件来认识一下枚举类
Compiled from "ColorEnum.java" public final class com.james.learning.j2se.enums.ColorEnum extends java.lang.Enum<com.james.learning.j2se.enums.ColorEnum> { public static final com.james.learning.j2se.enums.ColorEnum RED; public static final com.james.learning.j2se.enums.ColorEnum YELLOW; public static com.james.learning.j2se.enums.ColorEnum[] values(); Code: 0: getstatic #1 // Field $VALUES:[Lcom/james/learning/j2se/enums/ColorEnum; 3: invokevirtual #2 // Method "[Lcom/james/learning/j2se/enums/ColorEnum;".clone:()Ljava/lang/Object; 6: checkcast #3 // class "[Lcom/james/learning/j2se/enums/ColorEnum;" 9: areturn public static com.james.learning.j2se.enums.ColorEnum valueOf(java.lang.String); Code: 0: ldc #4 // class com/james/learning/j2se/enums/ColorEnum 2: aload_0 3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; 6: checkcast #4 // class com/james/learning/j2se/enums/ColorEnum 9: areturn static {}; Code: 0: new #4 // class com/james/learning/j2se/enums/ColorEnum 3: dup 4: ldc #7 // String RED 6: iconst_0 7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 10: putstatic #9 // Field RED:Lcom/james/learning/j2se/enums/ColorEnum; 13: new #4 // class com/james/learning/j2se/enums/ColorEnum 16: dup 17: ldc #10 // String YELLOW 19: iconst_1 20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 23: putstatic #11 // Field YELLOW:Lcom/james/learning/j2se/enums/ColorEnum; 26: iconst_2 27: anewarray #4 // class com/james/learning/j2se/enums/ColorEnum 30: dup 31: iconst_0 32: getstatic #9 // Field RED:Lcom/james/learning/j2se/enums/ColorEnum; 35: aastore 36: dup 37: iconst_1 38: getstatic #11 // Field YELLOW:Lcom/james/learning/j2se/enums/ColorEnum; 41: aastore 42: putstatic #1 // Field $VALUES:[Lcom/james/learning/j2se/enums/ColorEnum; 45: return }
从前面一句可以看出来
Compiled from "ColorEnum.java" public final class com.james.learning.j2se.enums.ColorEnum extends java.lang.Enum<com.james.learning.j2se.enums.ColorEnum> {
a. ColorEnum是final的,不能被再继承,也就是之后状态不能被覆盖。
b. ColorEnum继承自Enum.
public static final com.james.learning.j2se.enums.ColorEnum RED; public static final com.james.learning.j2se.enums.ColorEnum YELLOW; public static com.james.learning.j2se.enums.ColorEnum[] values();
这里我们看到成员变量RED、YELLOW 其实是一个 ColorEnum。自动会增加一个 values的方法返回ColorEnum[] 。
2. 为什么要用枚举
从effective java里摘出来的,像
public static final int TOTAL = 10;
public static final String MSG = "message";
这样的有以下几方面的问题:
1. 编译期无法感知是否用错,像入参的话可以直接用数字代替,数字还能做加减,这样不是常量的本意。
2. 如果是RPC,服务端的api里包含的常量,当服务端常量改变的时候,客户端需要跟着编译一次,当然也 可以不编译,但是做参数传递的话就会两端不一致。