android 中 我们通常推荐使用 @IntDef 等 代替使用 枚举,很多同学有疑问,为什么抛弃 枚举。我们现在就来一探究竟。
为什么枚举不行
- 枚举占据了较大的内存,而相比较来说 IntDef
枚举
- 每一个枚举就是一个对象。我们来看例子这是一个我们定义的枚举
public enum Test {
Ins, Ins2, IUns3
}
通过 javac 再 javap 查看他的bytecode
// class version 51.0 (51)
// access flags 0x4031
// signature Ljava/lang/Enum<Lcom/wt/emode/utils/Test;>;
// declaration: com/wt/emode/utils/Test extends java.lang.Enum<com.wt.emode.utils.Test>
public final enum com/wt/emode/utils/Test extends java/lang/Enum {
// compiled from: Test.java
// access flags 0x4019
public final static enum Lcom/wt/emode/utils/Test; Ins
// access flags 0x4019
public final static enum Lcom/wt/emode/utils/Test; Ins2
// access flags 0x4019
public final static enum Lcom/wt/emode/utils/Test; IUns3
// access flags 0x101A
private final static synthetic [Lcom/wt/emode/utils/Test; $VALUES
// access flags 0x9
public static values()[Lcom/wt/emode/utils/Test;
L0
LINENUMBER 3 L0
GETSTATIC com/wt/emode/utils/Test.$VALUES : [Lcom/wt/emode/utils/Test;
INVOKEVIRTUAL [Lcom/wt/emode/utils/Test;.clone ()Ljava/lang/Object;
CHECKCAST [Lcom/wt/emode/utils/Test;
ARETURN
MAXSTACK = 1
MAXLOCALS = 0
// access flags 0x9
public static valueOf(Ljava/lang/String;)Lcom/wt/emode/utils/Test;
L0
LINENUMBER 3 L0
LDC Lcom/wt/emode/utils/Test;.class
ALOAD 0
INVOKESTATIC java/lang/Enum.valueOf (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
CHECKCAST com/wt/emode/utils/Test
ARETURN
L1
LOCALVARIABLE name Ljava/lang/String; L0 L1 0
MAXSTACK = 2
MAXLOCALS = 1
// access flags 0x2
// signature ()V
// declaration: void <init>()
private <init>(Ljava/lang/String;I)V
L0
LINENUMBER 3 L0
ALOAD 0
ALOAD 1
ILOAD 2
INVOKESPECIAL java/lang/Enum.<init> (Ljava/lang/String;I)V
RETURN
L1
LOCALVARIABLE this Lcom/wt/emode/utils/Test; L0 L1 0
MAXSTACK = 3
MAXLOCALS = 3
// access flags 0x8
static <clinit>()V
L0
LINENUMBER 4 L0
NEW com/wt/emode/utils/Test
DUP
LDC "Ins"
ICONST_0
INVOKESPECIAL com/wt/emode/utils/Test.<init> (Ljava/lang/String;I)V
PUTSTATIC com/wt/emode/utils/Test.Ins : Lcom/wt/emode/utils/Test;
NEW com/wt/emode/utils/Test
DUP
LDC "Ins2"
ICONST_1
INVOKESPECIAL com/wt/emode/utils/Test.<init> (Ljava/lang/String;I)V
PUTSTATIC com/wt/emode/utils/Test.Ins2 : Lcom/wt/emode/utils/Test;
NEW com/wt/emode/utils/Test
DUP
LDC "IUns3"
ICONST_2
INVOKESPECIAL com/wt/emode/utils/Test.<init> (Ljava/lang/String;I)V
PUTSTATIC com/wt/emode/utils/Test.IUns3 : Lcom/wt/emode/utils/Test;
L1
LINENUMBER 3 L1
ICONST_3
ANEWARRAY com/wt/emode/utils/Test
DUP
ICONST_0
GETSTATIC com/wt/emode/utils/Test.Ins : Lcom/wt/emode/utils/Test;
AASTORE
DUP
ICONST_1
GETSTATIC com/wt/emode/utils/Test.Ins2 : Lcom/wt/emode/utils/Test;
AASTORE
DUP
ICONST_2
GETSTATIC com/wt/emode/utils/Test.IUns3 : Lcom/wt/emode/utils/Test;
AASTORE
PUTSTATIC com/wt/emode/utils/Test.$VALUES : [Lcom/wt/emode/utils/Test;
RETURN
MAXSTACK = 4
MAXLOCALS = 0
}
enum 集成自 java.lang.Enum 这个类 然后定义了三个 public final static enum xxx的实例
@IntDef 为什么比enum 好
@Retention(SOURCE) // 这里 源码级别 说明 只是在javac 编译期间做检查
@Target({ANNOTATION_TYPE})
public @interface IntDef {
/** Defines the allowed constants for this element */
int[] value() default {};
/** Defines whether the constants can be used as a flag, or just as an enum (the default) */
boolean flag() default false;
/**
* Whether any other values are allowed. Normally this is
* not the case, but this allows you to specify a set of
* expected constants, which helps code completion in the IDE
* and documentation generation and so on, but without
* flagging compilation warnings if other values are specified.
*/
boolean open() default false;
}