前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于Enum的再次理解

关于Enum的再次理解

作者头像
PhoenixZheng
发布2018-08-07 16:14:50
5720
发布2018-08-07 16:14:50
举报
文章被收录于专栏:Phoenix的Android之旅

问:enum 算不算基本数据类型 答:不算,enum是引用类型。

Java中的基本数据类型只有8种,分别是 byte、short、int、long、float、double、char、boolean

在 Java5之后新增的 Enum属于引用类型,跟 String一样也是属于类。 好奇的同学可能有疑问,既然说 enum是引用类型,为何在使用的时候没有见到类呢?

enum的使用场景

我们先来看一个简单的enum使用场景,

代码语言:javascript
复制
public class DayDemo {

    public enum Day {
      MONDAY,
      TUESDAY,
      WEDNESDAY,
      THURSDAY
    }

    public static void main(String[] args) {

    }
}

这里面只定义了一个枚举类型 Day, 通过枚举定义了周一到周四四种类型,后续我们使用的时候就可以直接用 Day.MONDAY 这样的方式来使用枚举值了。

为什么说枚举是类

在这代码里没有声明类,也没用其他的引用, 那么来看看编译后的结果

$ ls 'DayDemo$Day.class' DayDemo.class DayDemo.java

可以看到多了一个叫 DayDemo$Day.class的类出来, 从 class文件可以看出, 枚举 Day编译成了一个类,从这里可以断定虽然我们没有定义这个类, 但是编译器会把枚举作为类进行编译,从某种角度上来说 enum是一种语法糖, 现在来看一下 class文件的构造,

代码语言:javascript
复制
public final class DayDemo$Day extends java.lang.Enum<DayDemo$Day> {
  public static final DayDemo$Day MONDAY;

  public static final DayDemo$Day TUESDAY;

  public static final DayDemo$Day WEDNESDAY;

  public static final DayDemo$Day THURSDAY;

  public static DayDemo$Day[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[LDayDemo$Day;
       3: invokevirtual #2                  // Method "[LDayDemo$Day;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[LDayDemo$Day;"
       9: areturn

  public static DayDemo$Day valueOf(java.lang.String);
    Code:
       0: ldc           #4                  // class DayDemo$Day
       2: aload_0
       3: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       6: checkcast     #4                  // class DayDemo$Day
       9: areturn

  static {};
    Code:
       0: new           #4                  // class DayDemo$Day
       3: dup
       4: ldc           #7                  // String MONDAY
       6: iconst_0
       7: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #9                  // Field MONDAY:LDayDemo$Day;
      13: new           #4                  // class DayDemo$Day
      16: dup
      17: ldc           #10                 // String TUESDAY
      19: iconst_1
      20: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      23: putstatic     #11                 // Field TUESDAY:LDayDemo$Day;
      26: new           #4                  // class DayDemo$Day
      29: dup
      30: ldc           #12                 // String WEDNESDAY
      32: iconst_2
      33: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      36: putstatic     #13                 // Field WEDNESDAY:LDayDemo$Day;
      39: new           #4                  // class DayDemo$Day
      42: dup
      43: ldc           #14                 // String THURSDAY
      45: iconst_3
      46: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      49: putstatic     #15                 // Field THURSDAY:LDayDemo$Day;
      52: iconst_4
      53: anewarray     #4                  // class DayDemo$Day
      56: dup
      57: iconst_0
      58: getstatic     #9                  // Field MONDAY:LDayDemo$Day;
      61: aastore
      62: dup
      63: iconst_1
      64: getstatic     #11                 // Field TUESDAY:LDayDemo$Day;
      67: aastore
      68: dup
      69: iconst_2
      70: getstatic     #13                 // Field WEDNESDAY:LDayDemo$Day;
      73: aastore
      74: dup
      75: iconst_3
      76: getstatic     #15                 // Field THURSDAY:LDayDemo$Day;
      79: aastore
      80: putstatic     #1                  // Field $VALUES:[LDayDemo$Day;
      83: return
}

如果上面的代码不够简洁易懂的话可以看看下面翻译后的代码, 这只翻译 static代码段,其他的像 values和 valueOf都比较简单,

代码语言:javascript
复制
static
    {
        //实例化枚举实例
        MONDAY = new Day("MONDAY", 0);
        TUESDAY = new Day("TUESDAY", 1);
        WEDNESDAY = new Day("WEDNESDAY", 2);
        THURSDAY = new Day("THURSDAY", 3);
        $VALUES = (new Day[] {
            MONDAY, TUESDAY, WEDNESDAY, THURSDAY
        });
    }
总结

把这段代码和上面反编译的结果一起看的话就可以明白, 枚举类型在编译后会作为一个类生成, 编译器会帮我们插入 values和 valueOf 两个方法, 同时生成 final的常量, 在生成的静态代码段里会实例化好对应的枚举实例, 换句话说,我们所定义的每个枚举类,最终都会在它里面生成对应的静态常量,而常量的值就是我们所定义的值的String串。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Android每日一讲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • enum的使用场景
  • 为什么说枚举是类
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档