Java中的枚举(Enum)

基本概念

Java 枚举是一个特殊的类,一般表示一组常量,比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。

Java 枚举类使用 enum 关键字来定义,各个常量使用逗号(,)来分割。枚举类和正常类一样,也可以有成员变量、实例方法、静态方法、抽象方法

比如列举一个颜色的枚举类,包含红、黄、蓝三个属性

public class test1 {

    enum Color{
        RED,
        YELLOW,
        BLUE
    }

    public static void main(String[] args) {
        System.out.println(Color.RED);
        System.out.println(RED);
    }
}

每个枚举都是通过 Class 在内部实现的,且所有的枚举值都是 public static final 的。

以上的枚举类 Color 转化在内部类实现:

class Color
{
     public static final Color RED = new Color();
     public static final Color YELLOW= new Color();
     public static final Color BLUE= new Color();
}

values(), ordinal() 和 valueOf() 方法

enum 定义的枚举类默认继承了 java.lang.Enum 类,并实现了 java.lang.Seriablizable 和 java.lang.Comparable 两个接口。

values(), ordinal() 和 valueOf() 方法位于 java.lang.Enum 类中:

  • values() 返回枚举类中所有的值。
  • ordinal()方法可以找到每个枚举常量的索引,就像数组索引一样。
  • valueOf()方法返回指定字符串值的枚举常量。
public class test1 {

    enum Color{
        RED,
        YELLOW,
        BLUE
    }

    public static void main(String[] args) {
//        System.out.println(Color.RED);
//        System.out.println(RED);

        System.out.println(Arrays.toString(Color.values()));
        System.out.println(YELLOW.ordinal());
        System.out.println(Color.valueOf("YELLOW"));
    }
}

输出:

1. 枚举类常量

//枚举类是一个特殊的class
//这个class相当于使用final static修饰,不能被继承
//他的构造方法强制被私有化,每一个枚举类有一个默认的构造方法private ColorEnum();
//所有的枚举都继承自java.lang.Enum类。由于 Java 不支持多继承,所以枚举对象不能再继承其他类
public enum Color {
    //每个枚举变量都是枚举类Color的实例,相当于RED=new Color(1),按序号来。
    //每个成员变量都是final static修饰
    RED,YELLOW,BLUE
}

测试:

    public static void main(String[] args) {
        for (Color color : Color.values()) {
            System.out.println(color+",ordinal:"+color.ordinal()+",name:"+color.name());
        }
    }

结果:

2. 带参数的枚举

public class test2 {
    /**
     * Monday (周一)
     * Tuesday (周二)
     * Wednesday (周三)
     * Thursday (周四)
     * Friday (周五)
     * Saturday (周六)
     * Sunday (周日)
     */
    enum Week{
        MONDAY(1),
        TUESDAY(2),
        WEDNESDAY(3),
        THURSDAY(4),
        FRIDAY(5),
        SATURDAY(6),
        SUNDAY(7);
        private Integer num;
        private Week(Integer num){
            this.num=num;
        }

        public static Integer getNum(Week week){
            return week.num;
        }
    }

    public static void main(String[] args) {
        System.out.println(Week.getNum(Week.FRIDAY));
    }
}

结果:

3. 覆盖枚举的方法

public class test2 {
    enum Week{
        MONDAY(1),
        TUESDAY(2),
        WEDNESDAY(3),
        THURSDAY(4),
        FRIDAY(5),
        SATURDAY(6),
        SUNDAY(7);
        private Integer num;
        private Week(Integer num){
            this.num=num;
        }
        public static Integer getNum(Week week){
            return week.num;
        }

        @Override
        public String toString() {
            return this.name()+"_"+this.num;
        }
    }

    public static void main(String[] args) {
        for (Week week : Week.values()) {
            System.out.println(week.toString());
        }
    }
}

结果:

4.在Switch中使用枚举

public class test2 {
    enum Week{
        MONDAY(1),
        TUESDAY(2),
        WEDNESDAY(3),
        THURSDAY(4),
        FRIDAY(5),
        SATURDAY(6),
        SUNDAY(7);
        private Integer num;
        private Week(Integer num){
            this.num=num;
        }
        public static Integer getNum(Week week){
            return week.num;
        }

        @Override
        public String toString() {
            return this.name()+"_"+this.num;
        }
    }

    public static void main(String[] args) {
        Week thursday = Week.THURSDAY;
        switch (thursday){
            case MONDAY:
                System.out.println("星期一");
                break;
            case TUESDAY:
                System.out.println("星期二");
                break;
            case WEDNESDAY:
                System.out.println("星期三");
                break;
            case THURSDAY:
                System.out.println("星期四");
                break;
            case FRIDAY:
                System.out.println("星期五");
                break;
            case SATURDAY:
                System.out.println("星期六");
                break;
            case SUNDAY:
                System.out.println("星期天");
                break;
            default:
                System.out.println("输入错误");
        }
    }
}

结果:

5.实现接口

我们创建的枚举类默认是被final修饰,并且默认继承了Enum类。因此不能再继承其他的类。但是可以去实现接口。

有这样一个判断场景。

if ("dog".equals(animalType)){
    System.out.println("吃骨头");
} else if ("cat".equals(animalType)) {
    System.out.println("吃鱼干");
} else if ("sheep") {
    System.out.println("吃草");
}

怎样用枚举来消除掉 if/else 呐,看下面的代码:

先定义一个接口,里面有一个通用方法 eat()

public interface Eat {
    //吃
    String eat();
}

然后创建枚举类实现这个接口

public enum AnimalEnum implements Eat {
 
    Dog(){
        @Override
        public void eat() {
            System.out.println("吃骨头");
        }
    },
 
    Cat() {
        @Override
        public void eat() {
            System.out.println("吃鱼干");
        }
    },
 
    Sheep() {
        @Override
        public void eat() {
            System.out.println("吃草");
        }
    }
 
}

调用的时候只需要一行代码:

public class Test {
    public static void main(String[] args) {
        AnimalEnum.valueOf("Cat").eat(); // 吃鱼干
    }
}

6.枚举类中定义抽象方法

枚举类除了可以实现接口外,还可以在枚举类中定义抽象方法,这样每个枚举的对象只要分别实现了此抽象方法即可。

enum Color{
    RED{
        public String getColor(){//枚举对象实现抽象方法
            return "红色";
        }
    },
    GREEN{
        public String getColor(){//枚举对象实现抽象方法
            return "绿色";
        }
    },
    BLUE{
        public String getColor(){//枚举对象实现抽象方法
            return "蓝色";
        }
    };
    public abstract String getColor();//定义抽象方法
}


public class Test{
    public static void main(String[] args) {
        for (Color c:Color.values()){
            System.out.print(c.getColor() + "、");
        }
    }
}

7.枚举实现懒汉式单例

/**
 * @Description: 枚举  线程安全
 */
public class SingletonExample {
 
    /**
     * 构造函数私有化,避免外部创建实例
     */
    private SingletonExample(){}
 
    private static SingletonExample getInstance() {
        return Singleton.INSTANCE.getInstance();
    }
 
    private enum Singleton {
        INSTANCE;
        private SingletonExample instance;
 
        // JVM 保证这个方法绝对只调用一次
        Singleton() {
            instance = new SingletonExample();
        }
 
        public SingletonExample getInstance() {
            return instance;
        }
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/663764.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

android gradle8.3 发布插件踩过的坑

之前写过gradle6.x和gradle7.x的插件,会有一些改动,到8.x我发现又有一些变化,记录一下,防止后边再遇到相同的情况 下边是插件的gradle文件配置 plugins {id("java-gradle-plugin") //会自动引入java-library、gradleAp…

【Linux】 管道扩展 — 开始使用命名管道

送给大家一句话: 人生有六个字,前面三个是不害怕,后面三个是不后悔。 -- 董卿 🔆🔆🔆🔆🔆🔆🔆🔆 命名管道的功能实现 1 命名管道的原理2 代码实…

ROS2从入门到精通2-1:launch多节点启动与脚本配置

目录 0 专栏介绍1 ROS2的启动脚本优化2 ROS2多节点启动案例2.1 C架构2.2 Python架构 3 其他格式的启动文件3.1 .yaml启动3.2 .xml启动 0 专栏介绍 本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的…

博客星球大冒险:用Spring Boot和JWT打造你的数字王国

揭秘如何在Spring Boot中无缝集成JWT,为你的应用打造一个高度可扩展且安全的认证系统。从添加依赖到创建JWT过滤器,再到实现令牌的有效性管理和刷新机制,每一步都精心设计,确保你的乐园能够迎接成千上万的游客! 文章目…

AltiumDesigner/AD添加数据库连接

1.首先确保本机电脑有无对应的数据库驱动,例如我这边要添加MySQL的数据,则需要首先下载MySQL数据驱动:MySQL :: Download MySQL Connector/ODBC (Archived Versions) 2.运行“odbcad32.exe”,如下图添加对应的数据库配置&#xf…

基于深度学习的模糊认知图方法

1 文章信息 文章题目为“Deep Fuzzy Cognitive Maps for Interpretable Multivariate Time Series Prediction”,该文于2019年发表于“IEEE TRANSACTIONS ON FUZZY SYSTEMS”。文章提出了深度模糊认知图(FCM)用于多变量时间序列预测&#xff…

一个良好的嵌入式系统框架(基于FreeRTOS)

目录 Unix操作系统里的优先级嵌入式系统里的优先级 Unix操作系统里的优先级 在《Unix传奇》中有这样一句话,用户态的进程/线程是三等公民、root线程是二等公民、硬件中断是一等公民。 在操作系统中,"用户态"和"内核态"是两种不同的…

BERT模型学习(1)

BERT(Bidirectional Encoder Representations from Transformers)由谷歌在2018年推出,迅速成为自然语言处理(NLP)领域的一个突破性成果。 基本概念 在深入了解BERT之前,需要先简单了解一下自然语言处理&a…

五分钟“手撕”链表

为了提高大家的学习效率,我把代码放开头,供查阅。 目录 一、链表的实现代码 二、什么是链表 三、链表的分类 四、链表的常见操作 插入 删除 五、Java自带的LinkedList 两个构造方法 一些常用方法 六、LinkedList的遍历 七、ArrayList和Linke…

达梦数据库写文件的方式探索

0x01 前沿 这篇文章整体算是《达梦数据库手工注入笔记》的续集,达梦作为国内优秀的信创数据库,在关基单位中拥有越来越大的用户使用量。 通过SQL注入来写文件一直以来都是SQL注入漏洞深入利用的一种方式,对于不同的数据库通常写文件的方式也是…

探索无限可能性——微软 Visio 2021 改变您的思维方式

在当今信息化时代,信息流动和数据处理已经成为各行各业的关键。微软 Visio 2021 作为领先的流程图和图表软件,帮助用户以直观、动态的方式呈现信息和数据,从而提高工作效率,优化业务流程。本文将介绍 Visio 2021 的特色功能及其在…

【管理咨询宝藏119】翰威特组织架构设计优化方案

本报告首发于公号“管理咨询宝藏”,如需阅读完整版报告内容,请查阅公号“管理咨询宝藏”。 【管理咨询宝藏119】翰威特组织架构设计优化方案 【格式】PDF版本 【关键词】人力资源、组织设计、组织架构 【核心观点】 - 城镇化建设和居民可支配收入的增长…

Python实现定时任务的方式

大家好,在当今数字化的时代,定时任务的需求在各种应用场景中频繁出现。无论是数据的定时更新、周期性的任务执行,还是特定时间点的操作触发,Python 都为我们提供了强大而灵活的手段来实现这些定时任务。当我们深入探索 Python 的世…

代理 模式

一、什么是代理模式 代理模式指代理控制对其他对象的访问,也就是代理对象控制对原对象的引⽤。在某些情况下,⼀个对象不适合或者不能直接被引⽤访问,⽽代理对象可以在客⼾端和⽬标对象之间起到中介的作⽤。 二、为什么使用代理模式 模式作…

MySQL各种锁

目录 1. 从粒度上区分锁 1.1 全局锁(第一粒度) 1.2 表级锁(第二粒度) 1.3 行锁(第三最小粒度) 2 从模式上区分锁 2.1 什么是乐观锁 2.2 什么是悲观锁 2.3 意向共享锁和意向排他锁 2.4 临键锁和记录…

【Python】 深入理解Python中的UnicodeDecodeError及其解决方案

基本原理 在Python编程中,我们经常需要处理各种类型的数据,尤其是文本数据。文本数据在计算机中通常以字节的形式存在,而字节需要被解码成我们能够理解的字符。这个过程涉及到编码和解码的概念。 编码是将字符转换为字节的过程,…

23 vue3面试重难点复习:响应式原理、特点、8大生命钩子、data数据定义、组件、全家桶

vue作为用的最为广泛的当前热门框架,总结如下重难点核心知识: 1.vue特点是什么? 1.1优点 渐进式 vue本身只提供数据响应式,需要全局缓存用 vuex,需要路由用 vue-router 组件化 封装组件,利于复用 响应式数…

k8s——Pod进阶(资源限制和探针)

一、资源限制 1.1 资源限制的定义 当定义Pod时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是CPU和内存大小,以及其他类型的资源。 当为Pod中的容器指定了request资源时,调度器就使用该信息来决定将Pod调度到哪个节点上。当还为容器…

汇凯金业:量化交易有风险吗

量化交易是一种通过复杂的数学模型和算法在金融市场中进行高频和自动化交易的方式。尽管量化交易在提高市场效率、减少人为错误等方面具有诸多优点,但它也同样存在着不少风险。以下列举了一些主要的风险因素: 1. 模型风险 模型缺陷:量化交易…

网络协议。

一、流程案例 接下来揭秘我要说的大事情,“双十一”。这和我们要讲的网络协议有什么关系呢? 在经济学领域,有个伦纳德里德(Leonard E. Read)创作的《铅笔的故事》。这个故事通过一个铅笔的诞生过程,来讲述…