zoukankan      html  css  js  c++  java
  • java语法糖---枚举

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

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

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

    Java代码  
    1. public enum Sex {  
    2.          MALE,  
    3.          FEMALE  
    4. }  
    Java代码  
    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文件反编译,看一下每个方法里面都做了些什么东西。

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

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

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

    Java代码  
    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打开这些文件来看一下。

    Java代码  
    1. public class Sex extends Enum  
    2. {  
    3.    
    4.     public static Sex[] values()  
    5.     {  
    6.         return (Sex[])$VALUES.clone();  
    7.     }  
    8.    
    9.     public static Sex valueOf(String s)  
    10.     {  
    11.         return (Sex)Enum.valueOf(Sex, s);  
    12.     }  
    13.    
    14.     private Sex(String s, int i)  
    15.     {  
    16.         super(s, i);  
    17.     }  
    18.    
    19.     public static void main(String args[])  
    20.     {  
    21.     }  
    22.    
    23.    
    24.     public static final Sex MALE;  
    25.     public static final Sex FEMALE;  
    26.     private static final Sex $VALUES[];  
    27.    
    28.     static  
    29.     {  
    30.         MALE = new Sex("MALE", 0) {  
    31.    
    32.             public String toString()  
    33.             {  
    34.                 return "u6211u662Fu7537u4EBA";  
    35.             }  
    36.    
    37.         }  
    38. ;  
    39.         FEMALE = new Sex("FEMALE", 1) {  
    40.    
    41.             public String toString()  
    42.             {  
    43.                 return "u6211u662Fu5973u4EBA";  
    44.             }  
    45.    
    46.         }  
    47. ;  
    48.         $VALUES = (new Sex[] {  
    49.             MALE, FEMALE  
    50.         });  
    51.     }  
    52. }  
    53.    

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

  • 相关阅读:
    skywalking简介
    .Net Core微服务——Consul(4):搭建集群
    .Net Core微服务——Consul(3):健康检查
    .Net Core微服务——Consul(2):自动扩展、服务调用
    .Net Core微服务——Consul(1):服务发现
    SpringBoot数据访问之整合Mybatis配置文件
    SpringBoot数据访问之Druid启动器的使用
    SpringBoot数据访问之Druid数据源的自定义使用
    Spring Boot核心技术之Restful映射以及源码的分析
    SpringBoot之yaml语法及静态资源访问
  • 原文地址:https://www.cnblogs.com/01picker/p/4410156.html
Copyright © 2011-2022 走看看