今天有个同学说他没怎么用过枚举类让我给他讲解一下,他说看了这么多博客还是一团雾水。然后我搜了一下,发现都是写的啥呀!我来,如果这篇博客你还听不懂请狂喷我,暴躁老哥立马上线写下此版本,废话少说,下面开始介绍。

 为什么要用枚举?

如果你现在还是没使用到枚举或者对枚举不太了解,那么你的定位是初级Java程序员。枚举的好处真的太多了,下面列举几个常用场景:

替代显示静态常量

阿里的开发手册说不要使用魔法常量(不要直接将字面量赋值给变量,例如 String ip = "127.0.0.1";),也就是说当要使用常量的时候需要将常量写成静态常量引用,如下代码所示:

public class Demo1{
    public static final int MONDAY= 1;
    public static final int WEDNESDAY= 3;
    public static final int FRIDAY= 5; 
    public static final String IP = "127.0.0.1";

    // 其他代码。。。
    // 正确使用常量:String ip = IP; 
}

但是上述存在一些规范性问题,如果某个常量很多地方都要用到则每个类都要定义,如果需要频繁修改(IP地址)则每个地方都要修改。因此最好的办法就是写成枚举类,统一集中管理常量,且使用时只需要管常量名屏蔽常量具体是什么。这是非常常用的开发方法。

状态模式与单例模式

因为枚举类型是线程安全的,并且只会装载一次,设计者充分的利用了枚举的这个特性来实现单例模式,枚举的写法非常简单,而且枚举类型是所用单例实现中唯一一种不会被破坏的单例实现模式。

总而言之,枚举类非常重要,非常好用,狠狠地学它!

枚举类超级易懂讲解

很多地方直接给出代码,学习者只知其然,不知所以然。如下:

public enum Color {  
  RED, GREEN, BLANK, YELLOW  
}

然后,教你如何用,然后就完事了。学习者一脸懵逼,这个RED是什么类型?哪里定义了?为什么用的时候变成了String类型?。。。。等等问题,一头雾水,说到底是讲解者的问题!下面,将详细介绍其原理。

我们从最熟悉的类开始讲,先不讲枚举类(enum),因为枚举类到底还是类(class)。现在我给出如下代码:

public class Person { 
    // 成员变量
    private String name;
    private int age;
    private String address;
    
    // 构造方法
    Person(String name ,int age ,String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }

    // Get方法
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }
}

上面这段代码大家都能看懂,这不就是定义了一个Person类吗?你还有Set方法和toString方法没写!先别急,以上代码看懂了就可以了,其实你枚举类已经学会了!你内心:什么?你在讲什么哟!我啥都没学好不好!别急,看好了,上面代码99%不用改,只改两个地方就行,你就学会了枚举类,代码如下:

public enum Person {
    
    // 枚举类常量成员,类型为Person
    CHENEY("cheney", 18, "shanghai"),
    JIM("jim", 19, "beijing"),
    TOM("tom", 20, "shenzhen");

    // 枚举类成员变量
    private String name;
    private int age;
    private String address;

    Person(String name ,int age ,String address){
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }
}

听我说,上面只将class换成了enum,然后将对象直接实例化在了自己这个类中,而且实例化的对象不需要new关键字。看见了没?枚举类其实就是将对象实例化在自身类中的一种类,你可以把枚举类看作为一个关于自身类的对象集合。其中 CHENEY 常量对象类别时 Person,三个参数是Person的构造方法的参数,并且还有另外两个对象JIM和TOM。接下来看下如何使用:

public class Main {
    public static void main(String[] args) { 
        Person cheney = Person.CHENEY;
        // 下面两行 等价 System.out.println(cheney);
        String className = cheney.toString();
        System.out.println(className);  // 输出 CHENEY
        
        System.out.println(cheney.getName());
        System.out.println(cheney.getAge());
        System.out.println(cheney.getAddress()); 
    }
}

使用的时候很简单,可以通过 类.枚举对象名 即可获取枚举对象,然后就像使用普通对象一模一样。值得注意的地方有几点,首先,你难道不好奇CHENEY枚举对象是什么样的修饰符吗?答案是:


枚举值都是 public static final的自身类型!


并且枚举类的toString()方法默认返回枚举对象的名称。

java枚举类 菜鸟 java枚举类使用场景_Java enum类

 最后再看一下最常见的枚举类:

public enum Color {
    // 枚举值都是 public static final的自身类型
    RED, GREEN, BLUE;
}

// 等价于下面
class Color{
     public static final Color RED = new Color();
     public static final Color BLUE = new Color();
     public static final Color GREEN = new Color();
}

现在这个定义你可以看懂了吧?其实就是一个Color类,没有任何属性、构造方法和成员方法。没有就没有嘛,这些都没有也是一个class同意吧!但是做个两个关键变化,一个是class改成enum,另外一个就是实例化了三个枚举对象,默认修饰符号是 public static final 。另外,枚举类还提供了一些其他的类似集合的用法,如下:

public class Main {
    public static void main(String[] args) {
        Color red = Color.RED;
        System.out.println(red); // 输出枚举值的对象名称: RED
        // 类似集合,Color.values() 获取所有枚举值对象
        for(Color color:Color.values()){
            System.out.println(color);
            System.out.println(color.ordinal()); // 枚举值对象的顺序或者讲索引
        }
    }
}

最后

最后,我相信你已经懂了枚举类是什么了,其实就是一个定义了常量对象的类。和普通类没什么区别,唯一区别就是类中已经有本类的很多静态常量枚举值。那么最后给出对第一个提出的使用枚举类替代显示静态变量的枚举类实现:

public enum Week {
    MONDAY( 1),
    TUESDAY( 2),
    WEDNESDAY( 3),
    THURSDAY(4),
    FRIDAY(5),
    SATURDAY(6),
    SUNDAY(7);
    
    private int value;
    private Week(int value) {
        this.value = value;
    }
    public int getValue() {
        return value;
    }
}

对了,枚举类的构造方法的修饰符是private ,这个区别IDEA会提示的,记住就行!其他借助枚举类实现的功能,其实就是普通类+枚举类特点的实现,很简单!