枚举

枚举

  • Why:为什么需要枚举
  • What:枚举是什么;
  • How:枚举怎么实现
  • When:枚举什么时候使用
  • Where:枚举在哪里使用
  • Other:使用枚举会带来什么问题?

What:枚举是什么

How:枚举是怎么实现的

  • 实验代码
enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER;
}
  • 使用jad编译代码
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   Season.java
final class Season extends Enum
{

    public static Season[] values()
    {
        return (Season[])$VALUES.clone();
    }

    public static Season valueOf(String name)
    {
        return (Season)Enum.valueOf(EnumTest/Season, name);
    }

    private Season(String s, int i)
    {
        super(s, i);
    }

    public static final Season SPRING;
    public static final Season SUMMER;
    public static final Season AUTUMN;
    public static final Season WINTER;
    private static final Season $VALUES[];

    static 
    {
        SPRING = new Season("SPRING", 0);
        SUMMER = new Season("SUMMER", 1);
        AUTUMN = new Season("AUTUMN", 2);
        WINTER = new Season("WINTER", 3);
        $VALUES = (new Season[] {
            SPRING, SUMMER, AUTUMN, WINTER
        });
    }
}
  • 从jad编译得到的代码,可以看出创建了一个继承了EnumSeason类;
  • 每个枚举类型实质上是一个Season类对象的引用;

枚举的线程安全

  • 当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的。所以,创建一个enum类型是线程安全的

Enum

When and Where:枚举在什么时候可以使用

  • 单例

枚举和单例

  • 枚举是实现单例的推荐方式,原因是枚举可以保证线程安全和序列化的安全。

    • 为什么我墙裂建议大家使用枚举来实现单例。
    • Java Singletons Using Enum
  • 实现方式

    public enum Singleton {
        INSTANCE;
    }
    
  • 使用方式

    public static void main(String[] args)
    {
        Singleton s1 = Singleton.INSTANCE;
        Singleton s2 = Singleton.INSTANCE;
        System.out.println(s1 == s2); // 返回true
    }
    
  • 枚举解决了线程安全问题

    由枚举实现部分可以看出,枚举值实际是在静态块中初始化;当一个Java类第一次被真正使用到的时候静态资源被初始化、Java类的加载和初始化过程都是线程安全的(因为虚拟机在加载枚举的类的时候,会使用ClassLoader的loadClass方法,而这个方法使用同步代码块保证了线程安全)。所以,创建一个enum类型是线程安全的。

  • 枚举解决了反序列化会破坏单例的问题(学完序列化之后再细看)

你可能感兴趣的:(枚举)