java中枚举声明需用到enum关键字简单的如:
public enum TestEnum { Mon, Tue, Wen, Fri }
但是我们查看一下编译后得到的汇编就能知道,enum编译后得到的还是一个class,现在用javap -verbose TestEnum命令查看编译得到的class文件:
Classfile /F:/TestEnum.class Last modified 2017-5-8; size 868 bytes MD5 checksum 485a9071bf44ca9406beceea0dbca950 Compiled from "TestEnum.java" public final class TestEnum extends java.lang.Enum<TestEnum> minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM Constant pool: #1 = Fieldref #4.#38 // TestEnum.$VALUES:[LTestEnum; #2 = Methodref #39.#40 // "[LTestEnum;".clone:()Ljava/lang/Object; #3 = Class #23 // "[LTestEnum;" #4 = Class #41 // TestEnum #5 = Methodref #16.#42 // java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; #6 = Methodref #16.#43 // java/lang/Enum."<init>":(Ljava/lang/String;I)V #7 = String #17 // Mon #8 = Methodref #4.#43 // TestEnum."<init>":(Ljava/lang/String;I)V #9 = Fieldref #4.#44 // TestEnum.Mon:LTestEnum; #10 = String #19 // Tue #11 = Fieldref #4.#45 // TestEnum.Tue:LTestEnum; #12 = String #20 // Wen #13 = Fieldref #4.#46 // TestEnum.Wen:LTestEnum; #14 = String #21 // Fri #15 = Fieldref #4.#47 // TestEnum.Fri:LTestEnum; #16 = Class #48 // java/lang/Enum #17 = Utf8 Mon #18 = Utf8 LTestEnum; #19 = Utf8 Tue #20 = Utf8 Wen #21 = Utf8 Fri #22 = Utf8 $VALUES #23 = Utf8 [LTestEnum; #24 = Utf8 values #25 = Utf8 ()[LTestEnum; #26 = Utf8 Code #27 = Utf8 LineNumberTable #28 = Utf8 valueOf #29 = Utf8 (Ljava/lang/String;)LTestEnum; #30 = Utf8 <init> #31 = Utf8 (Ljava/lang/String;I)V #32 = Utf8 Signature #33 = Utf8 ()V #34 = Utf8 <clinit> #35 = Utf8 Ljava/lang/Enum<LTestEnum;>; #36 = Utf8 SourceFile #37 = Utf8 TestEnum.java #38 = NameAndType #22:#23 // $VALUES:[LTestEnum; #39 = Class #23 // "[LTestEnum;" #40 = NameAndType #49:#50 // clone:()Ljava/lang/Object; #41 = Utf8 TestEnum #42 = NameAndType #28:#51 // valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; #43 = NameAndType #30:#31 // "<init>":(Ljava/lang/String;I)V #44 = NameAndType #17:#18 // Mon:LTestEnum; #45 = NameAndType #19:#18 // Tue:LTestEnum; #46 = NameAndType #20:#18 // Wen:LTestEnum; #47 = NameAndType #21:#18 // Fri:LTestEnum; #48 = Utf8 java/lang/Enum #49 = Utf8 clone #50 = Utf8 ()Ljava/lang/Object; #51 = Utf8 (Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; { public static final TestEnum Mon; descriptor: LTestEnum; flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM public static final TestEnum Tue; descriptor: LTestEnum; flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM public static final TestEnum Wen; descriptor: LTestEnum; flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM public static final TestEnum Fri; descriptor: LTestEnum; flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM private static final TestEnum[] $VALUES; descriptor: [LTestEnum; flags: ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC public static TestEnum[] values(); descriptor: ()[LTestEnum; flags: ACC_PUBLIC, ACC_STATIC Code: stack=1, locals=0, args_size=0 0: getstatic #1 // Field $VALUES:[LTestEnum; 3: invokevirtual #2 // Method "[LTestEnum;".clone:()Ljava/lang/Object; 6: checkcast #3 // class "[LTestEnum;" 9: areturn LineNumberTable: line 1: 0 public static TestEnum valueOf(java.lang.String); descriptor: (Ljava/lang/String;)LTestEnum; flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=1, args_size=1 0: ldc #4 // class TestEnum 2: aload_0 3: invokestatic #5 // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; 6: checkcast #4 // class TestEnum 9: areturn LineNumberTable: line 1: 0 private TestEnum(); descriptor: (Ljava/lang/String;I)V flags: ACC_PRIVATE Code: stack=3, locals=3, args_size=3 0: aload_0 1: aload_1 2: iload_2 3: invokespecial #6 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V 6: return LineNumberTable: line 1: 0 Signature: #33 // ()V static {}; descriptor: ()V flags: ACC_STATIC Code: stack=4, locals=0, args_size=0 0: new #4 // class TestEnum 3: dup 4: ldc #7 // String Mon 6: iconst_0 7: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 10: putstatic #9 // Field Mon:LTestEnum; 13: new #4 // class TestEnum 16: dup 17: ldc #10 // String Tue 19: iconst_1 20: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 23: putstatic #11 // Field Tue:LTestEnum; 26: new #4 // class TestEnum 29: dup 30: ldc #12 // String Wen 32: iconst_2 33: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 36: putstatic #13 // Field Wen:LTestEnum; 39: new #4 // class TestEnum 42: dup 43: ldc #14 // String Fri 45: iconst_3 46: invokespecial #8 // Method "<init>":(Ljava/lang/String;I)V 49: putstatic #15 // Field Fri:LTestEnum; 52: iconst_4 53: anewarray #4 // class TestEnum 56: dup 57: iconst_0 58: getstatic #9 // Field Mon:LTestEnum; 61: aastore 62: dup 63: iconst_1 64: getstatic #11 // Field Tue:LTestEnum; 67: aastore 68: dup 69: iconst_2 70: getstatic #13 // Field Wen:LTestEnum; 73: aastore 74: dup 75: iconst_3 76: getstatic #15 // Field Fri:LTestEnum; 79: aastore 80: putstatic #1 // Field $VALUES:[LTestEnum; 83: return LineNumberTable: line 2: 0 line 3: 13 line 4: 26 line 5: 39 line 1: 52 } Signature: #35 // Ljava/lang/Enum<LTestEnum;>; SourceFile: "TestEnum.java"
现在一点一点解释
1.enum最终编译得到一个继承java.lang.Enum的final class(Enum的源码这里不做讲解,很简单)
2.这个类TestEnum类,有几个类型为自身的静态最终变量Mon、Tue、Wen、Fri也就是在enum中的几个声明,以及一个TestEnum[]数组变量$VALUES
3.静态方法values(),作用是返回该类的静态变量数组$VALUES
4.静态方法valueOf(),内部调用Enum类的方法
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) { //enumConstantDirectory返回一个第一次使用时懒加载的,简单名称与Enum实例 键值对的map T result = enumType.enumConstantDirectory().get(name); if (result != null) return result; if (name == null) throw new NullPointerException("Name is null"); throw new IllegalArgumentException( "No enum constant " + enumType.getCanonicalName() + "." + name); }
5.私有构造方法private TestEnum();内部就是调用enum的protected构造方法
6.静态代码块,它的作用是以枚举各个元素对应的String值和从0开始的int值为参数,依次初始化TestEnum对象并赋值给对应的静态最终变量(int值跟enum的ordinal相对应,String值跟enum的name相对应),接下来就是把这些静态变量值放到$VALUES数组中
所有枚举就是含有自身静态变量实例的类
相关推荐
Enum.doc Enum.docEnum.doc Enum.doc Enum.doc Enum.doc Enum.doc Enum.doc Enum.doc
Enum的用法Enum的用法Enum的用法Enum的用法
常见的enum类型重定义的解决方法,清晰明了。
选项Swift软件包,用于更强大的Enum类型。 目录介绍特征安装用法设置一个MappedValueRepresentable枚举使用MappedValueCollectionRepresented 使用MappedEnum类型的可编码枚举在ESet中使用OptionSet中的EnumSet 将...
用于枚举磁盘设备的 Enumdisk 示例
php-enum, PHP Enum实现灵感来自 SplEnum PHP enum 实现来自 SplEnum 为什么?首先,SplEnum 并不集成到PHP中,你必须单独安装它。使用 enum 而不是类常量提供了以下优点:你可以键入提示: function setAction(Ac
Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类Java SE程序 Enum枚举类...
enum测试代码
一个分析 enum 结构分析 源码资源
opc enum 32_64安装包
Laravel开发-enum PHP的枚举实现
java enum详细教程。由浅入深,包括基本语法方面..很适合新手学习。/n各位看官。绝对超值。
enum枚举的方法
简单介绍了DNS和ENUM的原理及在IMS网络中的使用
enum.docx ,详细介绍了enum的用法,枚举用法在c#中比较常见,希望会有帮助哦
C++中枚举类型(enum)
enum李兴华视频笔记,绝对值得看!
simple_enum, 支持ActiveModel的简单 enum ( 包括验证和 i18n ) SimpleEnum 对于ActiveRecord和 ruby,低调的枚举像字段一样,给ActiveRecord和Mongoid模型( 为 Rails 4 构建) 带来了枚举功能。从 2.0版本开始,...
Java enum的用法详解,可作为开发api
博文“Java 语言中 Enum 类型的使用介绍”的源码。