JAVA-Enum 枚举
【参考】枚举类名建议带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开。
说明:枚举其实就是特殊的类,域成员均为常量,且构造方法被默认强制是私有。
正例:枚举名字为 ProcessStatusEnum 的成员名称:SUCCESS / UNKNOWN_REASON。
创建一个枚举类
public enum DayEnum {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
使用
public class EnumTest {
    DayEnum day;
    public EnumTest(DayEnum day) {
        this.day = day;
    }
    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;
            case FRIDAY:
                System.out.println("Fridays are better.");
                break;
            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;
            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }
    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(DayEnum.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(DayEnum.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(DayEnum.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(DayEnum.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(DayEnum.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

带构造器枚举类
当存在字段和方法时,枚举常量列表必须以分号结尾,且定义枚举常量在字段和方法之前
枚举类型的构造函数必须是私有(没有修饰符默认为 private),不能自己手动调用枚举类的构造函数,JVM 会自动创建在枚举类中定义的常量。所以看似一样的枚举值一定不相等,因为这可能不是同一个对象实例
/**
* 行星上一个物体的重力和重量
*/
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6),
JUPITER(1.9e+27, 7.1492e7),
SATURN(5.688e+26, 6.0268e7),
URANUS(8.686e+25, 2.5559e7),
NEPTUNE(1.024e+26, 2.4746e7); // 以公斤为单位的
private final double mass;
// 以米为单位的
private final double radius; Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
} private double mass() {
return mass;
} private double radius() {
return radius;
} // 万有引力常数 (m3 kg-1 s-2)
public static final double G = 6.67300E-11; double surfaceGravity() {
return G * mass / (radius * radius);
} double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
使用
public static void main(String[] args) {
    double earthWeight = Double.parseDouble("175");
    double mass = earthWeight / EARTH.surfaceGravity();
    for (Planet p : Planet.values()) {
        System.out.printf("你在 %s 上的体重是 %f%n", p, p.surfaceWeight(mass));
    }
}

Enum 相关方法
public static void main(String[] args) {
    // 获取所有枚举常量
    DayEnum[] values = DayEnum.values();
    for (DayEnum value : values) {
        System.out.print(value);
        // 枚举常量在枚举类中的序号,零开始
        System.out.println("\t" + value.ordinal());
    }
    // 获取指定枚举常量,若不存在会报异常
    System.out.println(DayEnum.valueOf("SATURDAY"));
    System.out.println(DayEnum.valueOf(DayEnum.class, "SATURDAY"));
    // 比较枚举常量,与 == 方式相同,返回布尔值
    System.out.println(DayEnum.FRIDAY.equals(DayEnum.FRIDAY));
    // 比较枚举常量,采用 ordinal 序号方式,返回数字
    System.out.println(DayEnum.FRIDAY.compareTo(DayEnum.FRIDAY));
}

反编译 DayEnum
所有枚举类都隐式继承了抽象类 java.lang.Enum,用 javap 工具可以看到。所以枚举类不能继承其他类,JAVA 中为单继承,多实现
枚举常量会隐式被修饰成公共的静态常量,即枚举常量只会有一个实例,比较时可以使用 ==,枚举类的 equals 方法是 final 修饰
public final class javaenum.DayEnum extends java.lang.Enum<javaenum.DayEnum> {
  public static final javaenum.DayEnum SUNDAY;
  public static final javaenum.DayEnum MONDAY;
  public static final javaenum.DayEnum TUESDAY;
  public static final javaenum.DayEnum WEDNESDAY;
  public static final javaenum.DayEnum THURSDAY;
  public static final javaenum.DayEnum FRIDAY;
  public static final javaenum.DayEnum SATURDAY;
  public static javaenum.DayEnum[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[Ljavaenum/DayEnum;
       3: invokevirtual #2                  // Method "[Ljavaenum/DayEnum;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[Ljavaenum/DayEnum;"
       9: areturn
  public static javaenum.DayEnum valueOf(java.lang.String);
    Code:
       0: ldc           #4                  // class javaenum/DayEnum
       2: aload_0
       3: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       6: checkcast     #4                  // class javaenum/DayEnum
       9: areturn
  static {};
    Code:
       0: new           #4                  // class javaenum/DayEnum
       3: dup
       4: ldc           #7                  // String SUNDAY
       6: iconst_0
       7: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      10: putstatic     #9                  // Field SUNDAY:Ljavaenum/DayEnum;
      13: new           #4                  // class javaenum/DayEnum
      16: dup
      17: ldc           #10                 // String MONDAY
      19: iconst_1
      20: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      23: putstatic     #11                 // Field MONDAY:Ljavaenum/DayEnum;
      26: new           #4                  // class javaenum/DayEnum
      29: dup
      30: ldc           #12                 // String TUESDAY
      32: iconst_2
      33: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      36: putstatic     #13                 // Field TUESDAY:Ljavaenum/DayEnum;
      39: new           #4                  // class javaenum/DayEnum
      42: dup
      43: ldc           #14                 // String WEDNESDAY
      45: iconst_3
      46: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      49: putstatic     #15                 // Field WEDNESDAY:Ljavaenum/DayEnum;
      52: new           #4                  // class javaenum/DayEnum
      55: dup
      56: ldc           #16                 // String THURSDAY
      58: iconst_4
      59: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      62: putstatic     #17                 // Field THURSDAY:Ljavaenum/DayEnum;
      65: new           #4                  // class javaenum/DayEnum
      68: dup
      69: ldc           #18                 // String FRIDAY
      71: iconst_5
      72: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      75: putstatic     #19                 // Field FRIDAY:Ljavaenum/DayEnum;
      78: new           #4                  // class javaenum/DayEnum
      81: dup
      82: ldc           #20                 // String SATURDAY
      84: bipush        6
      86: invokespecial #8                  // Method "<init>":(Ljava/lang/String;I)V
      89: putstatic     #21                 // Field SATURDAY:Ljavaenum/DayEnum;
      92: bipush        7
      94: anewarray     #4                  // class javaenum/DayEnum
      97: dup
      98: iconst_0
      99: getstatic     #9                  // Field SUNDAY:Ljavaenum/DayEnum;
     102: aastore
     103: dup
     104: iconst_1
     105: getstatic     #11                 // Field MONDAY:Ljavaenum/DayEnum;
     108: aastore
     109: dup
     110: iconst_2
     111: getstatic     #13                 // Field TUESDAY:Ljavaenum/DayEnum;
     114: aastore
     115: dup
     116: iconst_3
     117: getstatic     #15                 // Field WEDNESDAY:Ljavaenum/DayEnum;
     120: aastore
     121: dup
     122: iconst_4
     123: getstatic     #17                 // Field THURSDAY:Ljavaenum/DayEnum;
     126: aastore
     127: dup
     128: iconst_5
     129: getstatic     #19                 // Field FRIDAY:Ljavaenum/DayEnum;
     132: aastore
     133: dup
     134: bipush        6
     136: getstatic     #21                 // Field SATURDAY:Ljavaenum/DayEnum;
     139: aastore
     140: putstatic     #1                  // Field $VALUES:[Ljavaenum/DayEnum;
     143: return
}
Enum 源码
/**
* 使用枚举类型作为 Collection 或 Map 中 Key 的类型时
* 可用 {@linkplain java.util.EnumSet set} 和 {@linkplain java.util.EnumMap map} 实现,专业且高效
*/
public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable {
// 枚举常量的名称,获取时使用{@link #toString}方法而不是访问此字段
private final String name; // 此方法主要用于在特殊情况下使用
public final String name() {
return name;
} // 此枚举常数的序数(其位置在枚举声明中,分配初始常量序数为零)
// 专门设计供复杂基于枚举的数据结构使用,例如 {@link java.util.EnumSet} 和 {@link java.util.EnumMap}
private final int ordinal; public final int ordinal() {
return ordinal;
} /**
* 唯一构造函数。程序员无法调用,由编译器调用
* @param name 枚举常量的名称,用于声明它的标识符
* @param ordinal 枚举常量的序数(声明它在枚举中的位置,初始常量的序数为零)
*/
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
} // 返回声明中包含的此枚举常量的名称,可以覆盖该方法
public String toString() {
return name;
} public final boolean equals(Object other) {
return this == other;
} public final int hashCode() {
return super.hashCode();
} // 保证了枚举类永远不会被克隆
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
} // 返回负整数,零或正整数
// 枚举常量只能与同一枚举类型的其他枚举常量相比较。此方法实现是根据 ordinal 值比较
public final int compareTo(E o) {
Enum<?> other = (Enum<?>) o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
} // 返回与此枚举常量的枚举类型对应的 Class 对象
@SuppressWarnings("unchecked")
public final Class<E> getDeclaringClass() {
Class<?> clazz = getClass();
Class<?> zuper = clazz.getSuperclass();
return (zuper == Enum.class) ? (Class<E>) clazz : (Class<E>) zuper;
} /**
* @param enumType 枚举类型的 Class 对象,用于从中返回常量
* @param name 要返回的常量的名称
* @param <T> 要返回常量的其枚举类型
* @return 具有指定名称的指定枚举类型的枚举常量
*/
public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name) {
T result = enumType.enumConstantDirectory().get(name);
if (result != null)
return result;
if (name == null)
throw new NullPointerException("Name is null");
throw new IllegalArgumentException("No enum constant " + enumType.getCanonicalName() + "." + name);
} // 枚举类不能有finalize方法
protected final void finalize() {} // 默认防止反序列化
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
} private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9
https://www.ibm.com/developerworks/cn/java/j-lo-enum/index.html
https://blog.csdn.net/javazejian/article/details/71333103
JAVA-Enum 枚举的更多相关文章
- 161208、Java enum 枚举还可以这么用
		
在大部分编程语言中,枚举类型都会是一种常用而又必不可少的数据类型,Java中当然也不会例外.然而,Java中的Enum枚举类型却有着许多你意想不到的用法,下面让我们一起来看看. 先来看一段代码示例: ...
 - Java enum枚举类型
		
java的枚举类型详解: 简单示例: public enum Color{ RED,BLUE,BLACK,YELLOW,GREEN } 复杂示例(带自定义构造方法与类型) public enum En ...
 - (转)java enum枚举
		
转载自: 原理:http://singleant.iteye.com/blog/686349 应用:http://www.cnblogs.com/happyPawpaw/archive/2013/04 ...
 - Java Enum枚举的用法(转)
		
说明:Java的枚举比dotnet的枚举好用,至少支持的方式有很多. 用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以 ...
 - Java Enum枚举 遍历判断 四种方式(包括 Lambda 表达式过滤)
		
示例代码如下: package com.miracle.luna.lambda; import java.util.Arrays; /** * @Author Miracle Luna * @Date ...
 - 简单认识java enum枚举
		
什么是枚举 枚举是java5中新增的特性,他是一个特殊的数据类型,他的特殊性在于他既是一种类类型,又比类类型多了安全性,简洁性,便捷性.java枚举类型是功能十分强大齐全的类,功能比其他语言中的对等物 ...
 - java enum(枚举)的使用
		
在实际编程中,往往存在着这样的“数据集”,它们的数值在程序中是稳定的,而且“数据集”中的元素是有限的. 例如星期一到星期日七个数据元素组成了一周的“数据集”,春夏秋冬四个数据元素组成了四季的“数据集” ...
 - java enum(枚举)使用详解 + 总结
		
enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性,存放在 java.lang 包中. 下面是我在使用 enum 过程中的一些经验和总结,主要包括如下内容: 1. 原始 ...
 - Java enum(枚举)的用法详解(转)
		
用法一:常量 在JDK1.5 之前,我们定义常量都是: public static fianl.... .现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法. p ...
 - Java ENUM枚举的用法
		
DK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 用法一:常量 在JDK1.5 之前,我们定义常量都是: publicstaticfianl... ...
 
随机推荐
- BZOJ3133[ballmachine]——倍增+优先队列
			
题目描述 有一个装球机器,构造可以看作是一棵树.有下面两种操作: 从根放入一个球,只要下方有空位,球会沿着树滚下.如果同时有多个点可以走,那么会选择编号最小的节点所在路径的方向.比如依次在树根4放2个 ...
 - HDU4651 Partition 【多项式求逆】
			
题目分析: 这题的做法是一个叫做五边形数定理的东西,我不会. 我们不难发现第$n$项的答案其实是: $$\prod_{i=1}^{\infty}\frac{1}{1-x^i}$$ 我们要对底下的东西求 ...
 - Django+Xadmin打造在线教育系统(二)
			
基于xadmin的后台管理 先使用pip进行安装xadmin及其依赖包 pip install django-adminx 安装完成后卸载xadmin,保留依赖包即可 pip uninstall dj ...
 - 「Splay」普通平衡树模板
			
口诀: $rotate$:先上再下,最后自己 $splay$:祖父未到旋两次,三点一线旋父亲,三点折线旋自己. $delete$:没有儿子就删光.单个儿子删自己.两个儿子找前驱. 易错点: $rota ...
 - CODEFORCES掉RATING记 #4
			
比赛:Codeforces Round #427 (Div. 2) 时间:2017.7.31晚 开场发现有6道题,都是水题(可能我只会做水题) A:比较\(2t_1+sv_1\)与\(2t_2+sv_ ...
 - Ajax传递List对象到前台展示问题遇到的坑
			
后台Json转换 后台传递的List对象,如果对象是实体类,实体类和另一个表关联,就可能会出现以下错误 org.hibernate.LazyInitializationException: faile ...
 - DNS 透明代理
			
DNS 透明代理 一.使用DNS负载均衡虚拟服务器(DNS * 53)的方式 --- 推荐使用的方式 注意:只会代理跨内网网段的DNS查询请求 ---------------------------- ...
 - TP5调用微信JSSDK 教程 - 测试成功案例
			
前提:必需了解TP5的全局配置,扩展目录,composer,依赖注入的概念: 第一步:首先配置加载官方JSSDK类 "autoload": { "files": ...
 - 用Nifi 从web api 取数据到HDFS
			
1. 全景图 2. 用ExecuteScript生成动态日期参数 为了只生成一个flowfile: Groovy 代码: import org.apache.commons.io. ...
 - day27
			
27.01 反射(类的加载概述和加载时机) 1.类的加载 当程序要使用某个类时,如果该类还未加载到内存中,系统会通知加载,连接,初始化三步来实现对这个类初始化 a.加载 是指将.class文件读入内存 ...