在JDK5.0中提供了大量的语法糖,例如:自动装箱拆箱、增强for循环、枚举、泛型等。所谓“语法糖”就是指提供更便利的语法供程序员使用,只是在编译器上做了手脚,却没有提供对应的指令集来处理它。

下面要介绍的是枚举这个语法糖的原理。

其实enum就是一个普通的类,它继承自java.lang.Enum类。

  1. public enum Sex {
  2. MALE,
  3. FEMALE
  4. }
  1. public final class Sex extends java.lang.Enum{
  2. public static final Sex MALE;
  3. public static final Sex FEMALE;
  4. public static Sex[] values();
  5. public static Sex valueOf(java.lang.String)
  6. static {};
  7. }

可以看出Sex编译成class文件之后,就变成发一个类,这个类是final的,所以enum是不可以被其他类继承的。由于enum已经继承了java.lang.Enum,所以enum不能再继承其他类。其中,enum中的每个枚举实例都是它自己的一个常量实例。除了这些,编译器还为我们生成了一个values方法。

下面再用DJ把这个enum的class文件反编译,看一下每个方法里面都做了些什么东西。

  1. public final class Sex extends Enum
  2. {
  3. public static Sex[] values()
  4. {
  5. return (Sex[])$VALUES.clone();
  6. }
  7. public static Sex valueOf(String s)
  8. {
  9. return (Sex)Enum.valueOf(Sex, s);
  10. }
  11. private Sex(String s, int i)
  12. {
  13. super(s, i);
  14. }
  15. public static final Sex MALE;
  16. public static final Sex FEMALE;
  17. private static final Sex $VALUES[];
  18. static
  19. {
  20. MALE = new Sex("MALE", 0);
  21. FEMALE = new Sex("FEMALE", 1);
  22. $VALUES = (new Sex[] {
  23. MALE, FEMALE
  24. });
  25. }
  26. }

在static块中初始化了两个enum实例,Sex枚举的构造方法有两个参数,第一个参数是枚举实例的名字,第二个参数是序列号(用ordinal方法可以获取到)。

我们还可以向每个枚举实例添加方法。

  1. public enum Sex {
  2. MALE {
  3. public String toString() {
  4. return "我是男人";
  5. }
  6. },
  7. FEMALE {
  8. public String toString() {
  9. return "我是女人";
  10. }
  11. };
  12. }

那这种情况下,编译器又为我们做了些什么动作呢?编译这个文件之后,我们可以看到生成了三个class文件,分别是Sex.class、Sex$1.class、Sex$2.class。它们分别是些什么东东,别急,我们用“神器”DJ打开这些文件来看一下。

  1. public class Sex extends Enum
  2. {
  3. public static Sex[] values()
  4. {
  5. return (Sex[])$VALUES.clone();
  6. }
  7. public static Sex valueOf(String s)
  8. {
  9. return (Sex)Enum.valueOf(Sex, s);
  10. }
  11. private Sex(String s, int i)
  12. {
  13. super(s, i);
  14. }
  15. public static void main(String args[])
  16. {
  17. }
  18. public static final Sex MALE;
  19. public static final Sex FEMALE;
  20. private static final Sex $VALUES[];
  21. static
  22. {
  23. MALE = new Sex("MALE", 0) {
  24. public String toString()
  25. {
  26. return "\u6211\u662F\u7537\u4EBA";
  27. }
  28. }
  29. ;
  30. FEMALE = new Sex("FEMALE", 1) {
  31. public String toString()
  32. {
  33. return "\u6211\u662F\u5973\u4EBA";
  34. }
  35. }
  36. ;
  37. $VALUES = (new Sex[] {
  38. MALE, FEMALE
  39. });
  40. }
  41. }

跟上面生成的class文件差不多,只是在static块中两个枚举实例的初始化变成了匿名内部类(这也就是为什么会多了两个class文件的原因了,^_^),在每个匿名内部类都有一个toString方法。

java语法糖---枚举的更多相关文章

  1. Java语法糖1:可变长度参数以及foreach循环原理

    语法糖 接下来几篇文章要开启一个Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的 ...

  2. Java语法糖设计

    语法糖 Java语法糖系列,所以首先讲讲什么是语法糖.语法糖是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这 ...

  3. Java语法糖(一)

    概述 语法糖(Syntactic Sugar):主要作用是提高编码效率,减少编码出错的机会. 解语法糖发生在Java源码被编译成Class字节码的过程中,还原回简单的基础语法结构. 语法糖之一:泛型( ...

  4. Java语法糖(二)

    语法糖之四:内部类 内部类:顾名思义,在类的内部在定义一个类.内部类仅仅是编译时的概念,编译成字节码后,内部类会生成单独的Class文件. 四种:成员内部类.局部内部类.匿名内部类.静态内部类. 1. ...

  5. Java 语法糖详解

    语法糖 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法. 这种语法对语言的功能并没有影响,但是 ...

  6. 深入理解java虚拟机(十二) Java 语法糖背后的真相

    语法糖(Syntactic Sugar),也叫糖衣语法,是英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语.指的是,在计算机语言中添加某种语法,这些语法糖虽然不会对语言 ...

  7. java语法糖:(1)可变长度参数以及foreach循环原理

    语法糖 语法糖:是一种几乎每种语言或多或少都提供过的一些方便程序员开发代码的语法,它只是编译器实现的一些小把戏罢了,编译期间以特定的字节码或者特定的方式对这些语法做一些处理,开发者就可以直接方便地使用 ...

  8. Java语法糖详解

    语法糖 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更 ...

  9. Java语法糖4:内部类

    内部类 最后一个语法糖,讲讲内部类,内部类指的就是在一个类的内部再定义一个类. 内部类之所以也是语法糖,是因为它仅仅是一个编译时的概念,outer.java里面定义了一个内部类inner,一旦编译成功 ...

随机推荐

  1. servlet文件下载2(单文件下载和批量下载)

    使用servlet完毕单文件下载和批量文件下载.批量下载的原理是先将文件打包成zip , 然后再下载. 之前也转载过一篇文件下载的博客,地址:http://blog.csdn.net/ch717828 ...

  2. UIview层次管理

    将一个UIView显示在最前面只需要调用其父视图的 bringSubviewToFront()方法. 将一个UIView层推送到背后只需要调用其父视图的 sendSubviewToBack()方法.

  3. Unity3D引擎之渲染技术系列一

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者.国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  4. 在Servlet的GenericServlet类中为什么有两个init()方法

    想要搞清楚这件事情,必须先了解Servlet容器调用Servlet的过程.调用过程如下 首次访问该Servlet1.调用init(ServletConfig config) 进行初始化,Servlet ...

  5. prometheus监控方案

    简介 prometheus 是一个开源的系统监控和告警的工具包,其采用pull方式采集时间序列,通过http协议传输. 架构 每个应用都通过javaagent向外提供一个http服务暴露出自己的JMX ...

  6. AR9331出现connect-debounce failed,port 1 disabled解决方法备忘

    基于AR9331的路由器,自己画的pcb板子,居然出现这个错误,百度下,貌似有不少人遇见过这个错误,可是在改动板子前我的固件用的是没问题的.USB完美使用 改动过板子后出现这个问题! hub 1-0: ...

  7. volatile的含义及使用场景

    volatile保证线程间的数据是可见的(共享的),但不保证数据同步 volatile相当于synchronized的弱实现,也就是说volatile实现了类似synchronized的语义,却又没有 ...

  8. ios 即时通讯 xmpp

    [iPhone高级] 基于XMPP的IOS聊天客户端程序(XMPP服务器架构) http://blog.csdn.NET/kangx6/article/details/7739828 [iPhone高 ...

  9. HTML5 - 新增的元素,删除的元素

    1,HTML5新增的元素(1)用于构建页面的语义元素:<article>,<aside>,<figcaption>,<figure>,<foote ...

  10. 如何通过Git命令行把代码提交到github上

    1.http://www.cnblogs.com/leesf456/p/5169765.html   参考博客 背景:最近入手了mac,看见mac上的大神都是在用git命令行推代码,我很羡慕有木有,好 ...