zoukankan      html  css  js  c++  java
  • java 枚举

    C 语言中可以这样来定义枚举

    [cpp] view plain copy
     
     print?
    1. enum color {  
    2.         RED=0, GREEN, BLUE, YELLOW  
    3. } col;  


    关键字 enum 定义枚举,在定义枚举的同时,声明该枚举变量 col.

    注意:C 语言中枚举成员的值是根据上下文自动加 1 的(GREEN = 1, BLUE = 2 等)。

    C 语言中 switch 语句支持枚举类型

    [cpp] view plain copy
     
     print?
    1. #include<stdio.h>  
    2. int main() {  
    3.     enum color {  
    4.         RED=0, GREEN, BLUE, YELLOW  
    5.     } col;  
    6.   
    7.     int cl;  
    8.   
    9.     printf("0=red,1=green,2=blue,3=yellow. seclect: ");  
    10.     scanf("%d",&cl);  
    11.   
    12.     col=(enum color) cl;  
    13.   
    14.     switch(col) {  
    15.         case RED:  
    16.             printf("the color is red ");  
    17.             break;  
    18.         case GREEN:  
    19.             printf("the color is green ");  
    20.             break;  
    21.         case BLUE:  
    22.              printf("the color is blue ");  
    23.             break;  
    24.         case YELLOW:  
    25.             printf("the color is yellow ");  
    26.             break;  
    27.         defalut:  
    28.             printf("no this color ");  
    29.             break;  
    30.     }  
    31.   
    32.     return 0;  
    33. }  


    那么,Java 里面的枚举与其类似,但是又不是完全一样。

    Java 语言中定义枚举也是使用关键字 enum

    [java] view plain copy
     
     print?
    1. public enum Color {  
    2.     RED, GREEN, BLUE, YELLOW;  
    3. }  

    上述定义了一个枚举类型 Color(可以说是类,编译之后是 Color.class).

    上面的定义,还可以改成下面的这种形式

    [java] view plain copy
     
     print?
    1. public enum Color {  
    2.     RED(), GREEN(), BLUE(), YELLOW();  
    3. }  


    到这里你就会觉得迷茫(如果你是初学者的话),为什么这样子也可以?

    其实,枚举的成员就是枚举对象,只不过他们是静态常量而已。

    使用 javap 命令(javap 文件名<没有后缀.class>)可以反编译 class 文件,如下:

    我们可以使用普通类来模拟枚举,下面定义一个 Color 类。

    [java] view plain copy
     
     print?
    1. public class Color {  
    2.     private static final Color RED = new Color();  
    3.     private static final Color GREEN = new Color();  
    4.     private static final Color BLUE = new Color();  
    5.     private static final Color YELLOW = new Color();  
    6. }  


    对比一下,你就明白了。

    如果按照这个逻辑,是否还可以为其添加另外的构造方法?答案是肯定的!

    [html] view plain copy
     
     print?
    1. public enum Color {  
    2.         RED("red color", 0), GREEN("green color", 1),   
    3.         BLUE("blue color", 2), YELLOW("yellow color", 3);  
    4.   
    5.         Color(String name, int id) {  
    6.             _name = name;  
    7.             _id = id;  
    8.         }  
    9.   
    10.         String _name;  
    11.         int _id;  
    12. }  

    为 Color 声明了两个成员变量,并为其构造带参数的构造器。

    如果你这样创建一个枚举

    [java] view plain copy
     
     print?
    1. public enum Color {  
    2.         RED("red color", 0), GREEN("green color", 1),   
    3.         BLUE("blue color", 2), YELLOW("yellow color", 3);  
    4. }  


    编译器就会报错

    [html] view plain copy
     
     print?
    1. The constructor EnumDemo.Color(String, int) is undefined  

    到此,你就可以明白,枚举和普通类基本一致(但是不完全一样)。

    对于类来讲,最好将其成员变量私有化,然后,为成员变量提供 get、set 方法。

    按照这个原则,可以进一步写好 enum Color.

    [java] view plain copy
     
     print?
    1. public enum Color {  
    2.         RED("red color", 0), GREEN("green color", 1),  
    3.         BLUE("blue color", 2), YELLOW("yellow color", 3);  
    4.   
    5.         Color(String name, int id) {  
    6.             _name = name;  
    7.             _id = id;  
    8.         }  
    9.   
    10.         private String _name;  
    11.         private int _id;  
    12.           
    13.         public void setName(String name) {  
    14.             _name = name;  
    15.         }  
    16.           
    17.         public void setId(int id) {  
    18.             _id = id;  
    19.         }  
    20.   
    21.         public String getName() {  
    22.             return _name;  
    23.         }  
    24.   
    25.         public int getId() {  
    26.             return _id;  
    27.         }  
    28. }  

    但是,java 设计 enum 的目的是提供一组常量,方便用户设计。

    如果我们冒然的提供 set 方法(外界可以改变其成员属性),好像是有点违背了设计的初衷。

    那么,我们应该舍弃 set 方法,保留 get 方法。

    [java] view plain copy
     
     print?
    1. public enum Color {  
    2.         RED("red color", 0), GREEN("green color", 1),  
    3.         BLUE("blue color", 2), YELLOW("yellow color", 3);  
    4.   
    5.         Color(String name, int id) {  
    6.             _name = name;  
    7.             _id = id;  
    8.         }  
    9.   
    10.         private String _name;  
    11.         private int _id;  
    12.           
    13.         public String getName() {  
    14.             return _name;  
    15.         }  
    16.   
    17.         public int getId() {  
    18.             return _id;  
    19.         }  
    20. }  


    普通类,我们可以将其实例化,那么,能否实例化枚举呢?

    在回答这个问题之前,先来看看,编译之后的 Color.class 文件

    [java] view plain copy
     
     print?
    1. public static enum Color {  
    2.         RED("red color", 0), GREEN("green color", 1),  
    3.         BLUE("blue color", 2), YELLOW("yellow color", 3);  
    4.   
    5.         private String _name;  
    6.         private int _id;  
    7.   
    8.         private Color(String name, int id) {  
    9.             this._name = name;  
    10.             this._id = id;  
    11.         }  
    12.   
    13.         public String getName() {  
    14.             return this._name;  
    15.         }  
    16.   
    17.         public int getId() {  
    18.             return this._id;  
    19.         }  
    20. }  


    可以看出,编译器淘气的为其构造方法加上了 private,那么也就是说,我们无法实例化枚举。

    所有枚举类都继承了 Enum 类的方法,包括 toString 、equals、hashcode 等方法。

    因为 equals、hashcode 方法是 final 的,所以不可以被枚举重写(只可以继承)。

    但是,可以重写 toString 方法。

    关于 Enum 源码,详见附录!

    那么,使用 Java 的不同类来模拟一下枚举,大概是这个样子

    [java] view plain copy
     
     print?
    1. package mark.demo;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. public class Color {  
    7.     private static final Color RED = new Color("red color", 0);  
    8.     private static final Color GREEN = new Color("green color", 1);  
    9.     private static final Color BLUE = new Color("blue color", 2);  
    10.     private static final Color YELLOW = new Color("yellow color", 3);  
    11.   
    12.     private final String _name;  
    13.     private final int _id;  
    14.   
    15.     private Color(String name, int id) {  
    16.         _name = name;  
    17.         _id = id;  
    18.     }  
    19.   
    20.     public String getName() {  
    21.         return _name;  
    22.     }  
    23.   
    24.     public int getId() {  
    25.         return _id;  
    26.     }  
    27.   
    28.     public static List<Color> values() {  
    29.         List<Color> list = new ArrayList<Color>();  
    30.         list.add(RED);  
    31.         list.add(GREEN);  
    32.         list.add(BLUE);  
    33.         list.add(YELLOW);  
    34.         return list;  
    35.     }  
    36.   
    37.     @Override  
    38.     public String toString() {  
    39.         return "the color _name=" + _name + ", _id=" + _id;  
    40.     }  
    41.   
    42. }  



    附录

     

    Enum.java

    [java] view plain copy
     
     print?
      1. /* 
      2.  * %W% %E% 
      3.  * 
      4.  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 
      5.  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 
      6.  */  
      7.   
      8. package java.lang;  
      9.   
      10. import java.io.Serializable;  
      11. import java.io.IOException;  
      12. import java.io.InvalidObjectException;  
      13. import java.io.ObjectInputStream;  
      14. import java.io.ObjectStreamException;  
      15.   
      16. /** 
      17.  * This is the common base class of all Java language enumeration types. 
      18.  * 
      19.  * @author  Josh Bloch 
      20.  * @author  Neal Gafter 
      21.  * @version %I%, %G% 
      22.  * @since   1.5 
      23.  */  
      24. public abstract class Enum<E extends Enum<E>>  
      25.         implements Comparable<E>, Serializable {  
      26.     /** 
      27.      * The name of this enum constant, as declared in the enum declaration. 
      28.      * Most programmers should use the {@link #toString} method rather than 
      29.      * accessing this field. 
      30.      */  
      31.     private final String name;  
      32.   
      33.     /** 
      34.      * Returns the name of this enum constant, exactly as declared in its 
      35.      * enum declaration. 
      36.      *  
      37.      * <b>Most programmers should use the {@link #toString} method in 
      38.      * preference to this one, as the toString method may return 
      39.      * a more user-friendly name.</b>  This method is designed primarily for 
      40.      * use in specialized situations where correctness depends on getting the 
      41.      * exact name, which will not vary from release to release. 
      42.      * 
      43.      * @return the name of this enum constant 
      44.      */  
      45.     public final String name() {  
      46.     return name;  
      47.     }  
      48.   
      49.     /** 
      50.      * The ordinal of this enumeration constant (its position 
      51.      * in the enum declaration, where the initial constant is assigned 
      52.      * an ordinal of zero). 
      53.      *  
      54.      * Most programmers will have no use for this field.  It is designed 
      55.      * for use by sophisticated enum-based data structures, such as 
      56.      * {@link java.util.EnumSet} and {@link java.util.EnumMap}. 
      57.      */  
      58.     private final int ordinal;  
      59.   
      60.     /** 
      61.      * Returns the ordinal of this enumeration constant (its position 
      62.      * in its enum declaration, where the initial constant is assigned 
      63.      * an ordinal of zero). 
      64.      *  
      65.      * Most programmers will have no use for this method.  It is 
      66.      * designed for use by sophisticated enum-based data structures, such 
      67.      * as {@link java.util.EnumSet} and {@link java.util.EnumMap}. 
      68.      * 
      69.      * @return the ordinal of this enumeration constant 
      70.      */  
      71.     public final int ordinal() {  
      72.     return ordinal;  
      73.     }  
      74.   
      75.     /** 
      76.      * Sole constructor.  Programmers cannot invoke this constructor. 
      77.      * It is for use by code emitted by the compiler in response to 
      78.      * enum type declarations. 
      79.      * 
      80.      * @param name - The name of this enum constant, which is the identifier 
      81.      *               used to declare it. 
      82.      * @param ordinal - The ordinal of this enumeration constant (its position 
      83.      *         in the enum declaration, where the initial constant is assigned 
      84.      *         an ordinal of zero). 
      85.      */  
      86.     protected Enum(String name, int ordinal) {  
      87.     this.name = name;  
      88.     this.ordinal = ordinal;  
      89.     }  
      90.   
      91.     /** 
      92.      * Returns the name of this enum constant, as contained in the 
      93.      * declaration.  This method may be overridden, though it typically 
      94.      * isn't necessary or desirable.  An enum type should override this 
      95.      * method when a more "programmer-friendly" string form exists. 
      96.      * 
      97.      * @return the name of this enum constant 
      98.      */  
      99.     public String toString() {  
      100.     return name;  
      101.     }  
      102.   
      103.     /** 
      104.      * Returns true if the specified object is equal to this 
      105.      * enum constant. 
      106.      * 
      107.      * @param other the object to be compared for equality with this object. 
      108.      * @return  true if the specified object is equal to this 
      109.      *          enum constant. 
      110.      */  
      111.     public final boolean equals(Object other) {   
      112.         return this==other;  
      113.     }  
      114.   
      115.     /** 
      116.      * Returns a hash code for this enum constant. 
      117.      * 
      118.      * @return a hash code for this enum constant. 
      119.      */  
      120.     public final int hashCode() {  
      121.         return super.hashCode();  
      122.     }  
      123.   
      124.     /** 
      125.      * Throws CloneNotSupportedException.  This guarantees that enums 
      126.      * are never cloned, which is necessary to preserve their "singleton" 
      127.      * status. 
      128.      * 
      129.      * @return (never returns) 
      130.      */  
      131.     protected final Object clone() throws CloneNotSupportedException {  
      132.     throw new CloneNotSupportedException();  
      133.     }  
      134.   
      135.     /** 
      136.      * Compares this enum with the specified object for order.  Returns a 
      137.      * negative integer, zero, or a positive integer as this object is less 
      138.      * than, equal to, or greater than the specified object. 
      139.      *  
      140.      * Enum constants are only comparable to other enum constants of the 
      141.      * same enum type.  The natural order implemented by this 
      142.      * method is the order in which the constants are declared. 
      143.      */  
      144.     public final int compareTo(E o) {  
      145.     Enum other = (Enum)o;  
      146.     Enum self = this;  
      147.     if (self.getClass() != other.getClass() && // optimization  
      148.             self.getDeclaringClass() != other.getDeclaringClass())  
      149.         throw new ClassCastException();  
      150.     return self.ordinal - other.ordinal;  
      151.     }  
      152.   
      153.     /** 
      154.      * Returns the Class object corresponding to this enum constant's 
      155.      * enum type.  Two enum constants e1 and  e2 are of the 
      156.      * same enum type if and only if 
      157.      *   e1.getDeclaringClass() == e2.getDeclaringClass(). 
      158.      * (The value returned by this method may differ from the one returned 
      159.      * by the {@link Object#getClass} method for enum constants with 
      160.      * constant-specific class bodies.) 
      161.      * 
      162.      * @return the Class object corresponding to this enum constant's 
      163.      *     enum type 
      164.      */  
      165.     public final Class<E> getDeclaringClass() {  
      166.     Class clazz = getClass();  
      167.     Class zuper = clazz.getSuperclass();  
      168.     return (zuper == Enum.class) ? clazz : zuper;  
      169.     }  
      170.   
      171.     /** 
      172.      * Returns the enum constant of the specified enum type with the 
      173.      * specified name.  The name must match exactly an identifier used 
      174.      * to declare an enum constant in this type.  (Extraneous whitespace 
      175.      * characters are not permitted.)  
      176.      * 
      177.      * @param enumType the <tt>Class</tt> object of the enum type from which 
      178.      *      to return a constant 
      179.      * @param name the name of the constant to return 
      180.      * @return the enum constant of the specified enum type with the 
      181.      *      specified name 
      182.      * @throws IllegalArgumentException if the specified enum type has 
      183.      *         no constant with the specified name, or the specified 
      184.      *         class object does not represent an enum type 
      185.      * @throws NullPointerException if <tt>enumType</tt> or <tt>name</tt> 
      186.      *         is null 
      187.      * @since 1.5 
      188.      */  
      189.     public static <T extends Enum<T>> T valueOf(Class<T> enumType,  
      190.                                                 String name) {  
      191.         T result = enumType.enumConstantDirectory().get(name);  
      192.         if (result != null)  
      193.             return result;  
      194.         if (name == null)  
      195.             throw new NullPointerException("Name is null");  
      196.         throw new IllegalArgumentException(  
      197.             "No enum const " + enumType +"." + name);  
      198.     }  
      199.   
      200.     /** 
      201.       * prevent default deserialization 
      202.       */  
      203.     private void readObject(ObjectInputStream in) throws IOException,  
      204.         ClassNotFoundException {  
      205.             throw new InvalidObjectException("can't deserialize enum");  
      206.     }  
      207.   
      208.     private void readObjectNoData() throws ObjectStreamException {  
      209.         throw new InvalidObjectException("can't deserialize enum");  
      210.     }  
      211.   
      212.     /** 
      213.      * enum classes cannot have finalize methods. 
      214.      */  
      215.     protected final void finalize() { }  
      216. }  
  • 相关阅读:
    linux 常用操作指令(随时更新)
    Spring @Scheduled应用解析
    H5的FormData对象完成ajax上传文件multiFile
    微服务的4个设计原则和19个解决方案
    微服务实战(六):如何做好服务拆分?
    微服务实战(五):微服务化之缓存的设计
    微服务实战(四):微服务化之无状态化与容器化
    微服务实战(三):以MySQL为例,从原理上理解那些所谓的数据库军规
    微服务实战(二):微服务的接入层设计与动静资源隔离
    微服务实战(一):微服务化的基石——持续集成
  • 原文地址:https://www.cnblogs.com/wangyage/p/7215854.html
Copyright © 2011-2022 走看看