zoukankan      html  css  js  c++  java
  • Java enum枚举类型

      java的枚举类型详解:

      简单示例:

    public enum Color{  
        RED,BLUE,BLACK,YELLOW,GREEN  
    }  

      复杂示例(带自定义构造方法与类型)

    public enum EnumTest {
         FRANK("The given name of me"),
         LIU("The family name of me");
         private String context;
         private String getContext(){
             return this.context;
         }
         private EnumTest(String context){
             this.context = context;
         }
         public static void main(String[] args){
             for(EnumTest name :EnumTest.values()){
                 System.out.println(name+" : "+name.getContext());
             }
             System.out.println(EnumTest.FRANK.getDeclaringClass());
         }
    } 

      显然,enum很像特殊的class,实际上enum声明定义的类型就是一个类。 而这些类都是类库中Enum类的子类(java.lang.Enum<E>)。它们继承了这个Enum中的许多有用的方法。而继承是编译器根据类型声明(public enum)自动加上的。

      我们对代码编译之后发现,编译器将enum类型单独编译成了一个字节码文件:Color.class。 

    final enum hr.test.Color {
      
     // 所有的枚举值都是类静态常量
    &nbsp;public static final enum hr.test.Color RED;
    &nbsp;public static final enum hr.test.Color BLUE;
     public static final enum hr.test.Color BLACK;
     public static final enum hr.test.Color YELLOW;
     public static final enum hr.test.Color GREEN;
     
    private static final synthetic hr.test.Color[] ENUM$VALUES;
      
      // 初始化过程,对枚举类的所有枚举值对象进行第一次初始化
    &nbsp;static {
           0  new hr.test.Color [1] 
          3  dup
          4  ldc <String "RED"> [16] //把枚举值字符串"RED"压入操作数栈
          6  iconst_0  // 把整型值0压入操作数栈
          7  invokespecial hr.test.Color(java.lang.String, int) [17] //调用Color类的私有构造器创建Color对象RED
         10  putstatic hr.test.Color.RED : hr.test.Color [21]  //将枚举对象赋给Color的静态常量RED。
          .........  枚举对象BLUE等与上同
        102  return
    };
      
      // 私有构造器,外部不可能动态创建一个枚举类对象(也就是不可能动态创建一个枚举值)。
     private Color(java.lang.String arg0, int arg1){
         // 调用父类Enum的受保护构造器创建一个枚举对象
         3  invokespecial java.lang.Enum(java.lang.String, int) [38]
    };
    &nbsp;
     public static hr.test.Color[] values();
      
       // 实现Enum类的抽象方法  
      public static hr.test.Color valueOf(java.lang.String arg0);
    }

      枚举类型中的每一个枚举,其实都是自己声明枚举(或者叫声明类)的一个静态实例

      因为构造器是Enum的构造器是protected的,所以外部是不能创建一个实例的,子类Enum可以看出来,构造器是private的,所以只有自己的几个枚举类型才能创建自己的实例。

      枚举类的特征及其用法:

      1、Color枚举类就是class,而且是一个不可以被继承的final类。其枚举值(RED,BLUE...)都是Color类型的类静态常量, 我们可以通过下面的方式来得到Color枚举类的一个实例:
                                                             Color c=Color.RED; 
      注意:这些枚举值都是public static final的,也就是我们经常所定义的常量方式,因此枚举类中的枚举值最好全部大写。 

      2、即然枚举类是class,当然在枚举类型中有构造器,方法和数据域。但是,枚举类的构造器有很大的不同: 
          (1) 构造器只是在构造枚举值的时候被调用。

    enum Color{
                    RED(255,0,0),BLUE(0,0,255),BLACK(0,0,0),YELLOW(255,255,0),GREEN(0,255,0);
                    //构造枚举值,比如RED(255,0,0)
                    private Color(int rv,int gv,int bv){
                     this.redValue=rv;
                     this.greenValue=gv;
                     this.blueValue=bv;
                    }
    
                    public String toString(){  //覆盖了父类Enum的toString()
                    return super.toString()+"("+redValue+","+greenValue+","+blueValue+")";
                    }
       
                    private int redValue;  //自定义数据域,private为了封装。
                    private int greenValue;
                    private int blueValue;
     }

       (2) 构造器只能私有private,绝对不允许有public构造器。 这样可以保证外部代码无法新构造枚举类的实例。这也是完全符合情理的,因为我们知道枚举值是public static final的常量而已。 但枚举类的方法和数据域可以允许外部访问。 

    public static void main(String args[])
    {
            // Color colors=new Color(100,200,300);  //wrong
               Color color=Color.RED;
               System.out.println(color);  // 调用了toString()方法
    }   

      3、所有枚举类都继承了Enum的方法,下面我们详细介绍这些方法。 

        Enum的构造方法为:protected  Enum(String name, int ordinal)  

       (0)  String name() 返回此枚举常量的名称,在其枚举声明中对其进行声明。

       (1)  ordinal()方法: 返回枚举值在枚举类种的顺序。这个顺序根据枚举值声明的顺序而定。
                     Color.RED.ordinal();  //返回结果:0
                     Color.BLUE.ordinal();  //返回结果:1
           (2)  compareTo()方法: Enum实现了java.lang.Comparable接口,因此可以比较象与指定对象的顺序。Enum中的compareTo返回的是两个枚举值的顺序之差。当然,前提是两个枚举值必须属于同一个枚举类,否则会抛出ClassCastException()异常。(具体可见源代码)
                     Color.RED.compareTo(Color.BLUE);  //返回结果 -1
           (3)  values()方法: 静态方法,返回一个包含全部枚举值的数组。
                     Color[] colors=Color.values();
                     for(Color c:colors){
                            System.out.print(c+","); 
                     }//返回结果:RED,BLUE,BLACK YELLOW,GREEN,
           (4)  toString()方法: 返回枚举常量的名称。
                     Color c=Color.RED;
                     System.out.println(c);//返回结果: RED
           (5)  valueOf()方法: 这个方法和toString方法是相对应的,返回带指定名称的指定枚举类型的枚举常量。

         static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)  
                     Color.valueOf("BLUE");   //返回结果: Color.BLUE
           (6)  equals()方法: 比较两个枚举类对象的引用。

       (7)  Class<E> getDeclaringClass()  返回与此枚举常量的枚举类型相对应的 Class 对象。当且仅当 e1.getDeclaringClass() == e2.getDeclaringClass() 时,两个枚举常量 e1 和 e2 的枚举类型才相同。(由该方法返回的值不同于由 Object.getClass() 方法返回的值,Object.getClass() 方法用于带有特定常量的类主体的枚举常量。) 

      同时该类覆盖了Object的clone()方法和finalize()方法,抛出异常,防止调用enum的析构方法

      4、枚举类可以在switch语句中使用。

    Color color=Color.RED;
    switch(color){
            case RED: System.out.println("it's red");break;
            case BLUE: System.out.println("it's blue");break;
            case BLACK: System.out.println("it's blue");break;
    }
  • 相关阅读:
    Python使用SMTP模块、email模块发送邮件
    harbor搭建及使用
    ELK搭建-windows
    ELK技术栈之-Logstash详解
    【leetcode】1078. Occurrences After Bigram
    【leetcode】1073. Adding Two Negabinary Numbers
    【leetcode】1071. Greatest Common Divisor of Strings
    【leetcode】449. Serialize and Deserialize BST
    【leetcode】1039. Minimum Score Triangulation of Polygon
    【leetcode】486. Predict the Winner
  • 原文地址:https://www.cnblogs.com/guangshan/p/4885104.html
Copyright © 2011-2022 走看看