1、引入


1_数学:枚举法

在数学中的示例:

1<x<4 
2<y<5 
求x+y=6 

枚举法:一枚一枚的列举出来。前提:有限,确定


2_定义

在java中,类的对象是有限个,确定的。这个类我们可以定义为枚举类。

Java 枚举(enum)是一种特殊的数据类型,用于定义一组固定的常量。它可以用于表示一组相关的值,例如季节、方向、状态等。Java 枚举类型的设计初衷是提供一种类型安全且可读性强的方式来表示固定的常量集合

举例:

  • 星期:一二三四五六日
  • 性别:男女
  • 季节:春夏秋冬

3_自定义枚举类:(JDK1.5之前自定义枚举类)

在 JDK1.5 之前,都是使用以下方式来实现枚举类功能的

package com.shen.enum01;

/**
 * @author : shenyang
 * 定义枚举类:季节
 */
public class Season {
    
    //属性:
    private final String seasonName;//季节名字
    private final String seasonDesc;//季节描述

    //利用构造器对属性进行赋值操作:
    //构造器私有化,外界不能调用这个构造器,只能Season内部自己调用
    private Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //提供枚举类的有限的  确定的对象:
    public static final Season SPRING = new Season("春天", "春暖花开");
    public static final Season SUMMER = new Season("夏天", "烈日炎炎");
    public static final Season AUTUMN = new Season("秋天", "硕果累累");
    public static final Season WINTER = new Season("冬天", "冰天雪地");

    //额外因素:
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //toString();
    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }

}

2、使用 enum 关键字来创建枚举类


1_创建枚举

JDK1_5 之后变为使用如下的枚举类:

package com.shen.enum02;

/**
 * @author : shenyang
 * 定义枚举类:季节
 */
public enum Season {
    //提供枚举类的有限的  确定的对象:--->enum枚举类要求对象(常量)必须放在最开始位置
    //多个对象之间用,进行连接,最后一个对象后面用;结束
    SPRING("春天", "春暖花开"),
    SUMMER("夏天", "烈日炎炎"),
    AUTUMN("秋天", "硕果累累"),
    WINTER("冬天", "冰天雪地");
    //属性:
    private final String seasonName;//季节名字
    private final String seasonDesc;//季节描述

    //利用构造器对属性进行赋值操作:
    //构造器私有化(枚举类型的构造方法默认就是私有的),外界不能调用这个构造器,只能Season内部自己调用
    private Season(String seasonName, String seasonDesc) {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //额外因素:
    public String getSeasonName() {
        return seasonName;
    }

    public String getSeasonDesc() {
        return seasonDesc;
    }

    //toString();
    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

测试枚举类:

public class TestSeason {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        Season winter = Season.WINTER;
        System.out.println(winter);
        //enum关键字对应的枚举类的上层父类是 :java.lang.Enum
        //但是我们自定义的枚举类的上层父类:Object
        System.out.println(Season.class.getSuperclass().getName());//java.lang.Enum
    }
}

在源码中经常看到别人定义的枚举类形态:

public enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER;
}

为什么这么简单:因为这个枚举类底层没有属性,属性,构造器,toString,get 方法。

这些都删掉不写了,然后按理来说应该写为:SPRING()。现在连()都可以省略变成 SPRING

看到的形态就剩:常量名(对象名)


2_案例

Thread 中的枚举类:State

public enum State {
    /**
     * Thread state for a thread which has not yet started.
     */
    NEW,

    /**
     * Thread state for a runnable thread.  A thread in the runnable
     * state is executing in the Java virtual machine but it may
     * be waiting for other resources from the operating system
     * such as processor.
     */
    RUNNABLE,

    /**
     * Thread state for a thread blocked waiting for a monitor lock.
     * A thread in the blocked state is waiting for a monitor lock
     * to enter a synchronized block/method or
     * reenter a synchronized block/method after calling
     * {@link Object#wait() Object.wait}.
     */
    BLOCKED,

    /**
     * Thread state for a waiting thread.
     * A thread is in the waiting state due to calling one of the
     * following methods:
     * <ul>
     *   <li>{@link Object#wait() Object.wait} with no timeout</li>
     *   <li>{@link #join() Thread.join} with no timeout</li>
     *   <li>{@link LockSupport#park() LockSupport.park}</li>
     * </ul>
     *
     * <p>A thread in the waiting state is waiting for another thread to
     * perform a particular action.
     *
     * For example, a thread that has called <tt>Object.wait()</tt>
     * on an object is waiting for another thread to call
     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
     * that object. A thread that has called <tt>Thread.join()</tt>
     * is waiting for a specified thread to terminate.
     */
    WAITING,

    /**
     * Thread state for a waiting thread with a specified waiting time.
     * A thread is in the timed waiting state due to calling one of
     * the following methods with a specified positive waiting time:
     * <ul>
     *   <li>{@link #sleep Thread.sleep}</li>
     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
     *   <li>{@link #join(long) Thread.join} with timeout</li>
     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
     * </ul>
     */
    TIMED_WAITING,

    /**
     * Thread state for a terminated thread.
     * The thread has completed execution.
     */
    TERMINATED;
}

3、Enum 类


1_特性

类型安全: 枚举提供了类型安全性,意味着不能将不属于枚举类型的值赋给它。

内置方法: 每个枚举类型都自动继承了 java.lang.Enum,并且在 Enum 类中存在一个名为 name 的属性用来表示枚举常量的名称。

因此拥有一些有用的方法,例如:

  • values():返回包含所有枚举常量的数组。
  • valueOf(String name):返回与指定名称匹配的枚举常量。
  • toString():返回此枚举常量的名称,如声明中包含的名称。

可扩展性:可以为枚举定义字段、方法和构造器。


2_方法使用示例

下面示例中演示了枚举类型中常用方法的使用

package com.shen.enum03;

/**
 * @author : shenyang
 */
public class TestSeason {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        //用enum关键字创建的Season枚举类上面的父类是:java.lang.Enum,常用方法子类Season可以直接拿过来使用:
        //toString();--->获取对象的名字
        Season autumn = Season.AUTUMN;
        System.out.println(autumn/*.toString()*/);//AUTUMN

        System.out.println("--------------------");
        //values:返回枚举类对象的数组
        Season[] values = Season.values();
        for (Season s : values) {
            System.out.println(s/*.toString()*/);
        }

        System.out.println("--------------------");
        //valueOf:通过对象名字获取这个枚举对象
        //注意:对象的名字必须传正确,否则抛出异常
        Season autumn1 = Season.valueOf("AUTUMN");
        System.out.println(autumn1);
    }
}

4、枚举类实现接口

1.定义一个接口:

public interface TestInterface {
	    void show();
}

2.枚举类实现接口,并且重写show方法:

public enum Season implements TestInterface {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER;

    @Override
    public void show() {
        System.out.println("这是Season....");
    }
}

3.测试类:

public class Test {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        Season autumn = Season.AUTUMN;
        autumn.show();
        Season summer = Season.SUMMER;
        summer.show();
    }
}

上面发现所有的枚举对象,调用这个 show 方法的时候走的都是同一个方法,结果都一样:

但是现在我想要:不同的对象 调用的 show 方法也不同:

package com.shen.enum04;


import java.sql.SQLOutput;

public enum Season implements TestInterface {
    SPRING{
        @Override
        public void show() {
            System.out.println("这是春天。。。");
        }
    },
    SUMMER{
        @Override
        public void show() {
            System.out.println("这是夏天。。");
        }
    },
    AUTUMN{
        @Override
        public void show() {
            System.out.println("这是秋天");
        }
    },
    WINTER{
        @Override
        public void show() {
            System.out.println("这是冬天");
        }
    };

    /*@Override
    public void show() {
        System.out.println("这是Season....");
    }*/
}

测试类:

public class Test {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        Season autumn = Season.AUTUMN;
        autumn.show();
        Season summer = Season.SUMMER;
        summer.show();
    }
}

5、实际应用

人实体类

package com.shen.enum05;

/**
 * @author : shenyang
 */
public class Person {
    //属性:
    private int age;
    private String name;
    private Gender sex;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Gender getSex() {
        return sex;
    }

    public void setSex(Gender sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

性别枚举类

public enum Gender {,;
}

测试

public class Test {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        Person p = new Person();
        p.setAge(19);
        p.setName("lili");
        p.setSex(Gender.);//传入枚举类Gender的对象:-->在入口处对参数进行了限制
        System.out.println(p);
    }
}

还可以通过枚举结合 switch 处理:

public class Test02 {
    //这是一个main方法,是程序的入口:
    public static void main(String[] args) {
        Gender sex = Gender.;
        //switch后面的()中可以传入枚举类型
        //switch后面的():int,short,byte,char,String ,枚举
        switch (sex){
            case:
                System.out.println("是个女孩");
                break;
            case:
                System.out.println("是个男孩");
                break;
        }
    }
}

6、总结

Java 枚举是一种强大的工具,提供了一种类型安全、可读性强的方式来定义一组固定的常量。通过结合字段、方法和构造器,枚举不仅可以表示简单的常量集合,还可以包含更复杂的数据和行为。


Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐