Java枚举详解

一、什么是枚举类型

        枚举类型是一种特殊的数据类型,用于定义一组固定的命名常量。枚举类型提供了一种更强大、更安全和更易读的方式来表示一组相关的常量。

        在Java中,枚举类型是通过使用enum关键字来定义的。枚举类型可以包含一个或多个枚举常量,每个常量都是枚举类型的实例。枚举常量是在枚举类型中预先定义的,它们是唯一的、已命名的对象。

        在Java中,枚举类型是一组固定常量值的集合,每个常量值代表一个特定的数据类型。枚举在Java中被视为数据类型,你可以使用它们来创建枚举类型的变量、数组、参数等。

二、枚举的引入

要求创建一个季节(Season)类,只能创建春夏秋冬4个对象。

  • 旧方法:假如按照以往的思路,只能创建一个普通的Season 类。
  • 代码如下:

public class Enumeration01 {
   public static void main(String[] args) {
       //使用
       Season spring = new Season("春天", "温暖");
       Season winter = new Season("冬天", "寒冷");
       Season summer = new Season("夏天", "炎热");
       Season autumn = new Season("秋天", "凉爽");
       Season other = new Season("红天", "~~~");// 可以随意多创建对象,不满足题目要求
//     autumn.setName("XXX");// 会改变对象的属性,不满足题目的要求
//     autumn.setDesc("非常的热..");
   }
}
class Season{//类
   private String name;
   private String desc;// 季节描述

   public Season(String name, String desc) {
       this.name = name;
       this.desc = desc;
   }

   public String getName() {
       return name;
   }

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

   public String getDesc() {
       return desc;
   }

   public void setDesc(String desc) {
       this.desc = desc;
   }
}

        思考:使用普通类的定义,我们不能体现Season 类只有4个固定的对象,因为使用者可以随意创建更多的对象。因此我们需要一种特殊的类,可以限制使用者创建的对象的个数与类型 ---- 于是便引入了枚举类。
        枚举(enumeration):枚举是一组常量的集合;它是一种特殊的类,里面只包含一组有限的特殊的不能修改的对象。

三、枚举的基本用法

  • 使用 enum 关键字实现枚举:

使用步骤:
(1)使用 enum 关键字取代 class 关键字定义一个类,该类便称为枚举类。
(2)在枚举类内部直接创建对象,枚举类对象是默认使用 public static final 一起修饰的,如果有多个对象,则必须且只能使用(,)间隔开。
(3)在枚举类中将构造器私有化,防止外部随意创建枚举类对象。
(4)只保留属性的get 方法,不提供属性的 set 方法,防止枚举类的对象属性被更改。

  • 将上例代码修改如下:

public class Enumeration03 {
    public static void main(String[] args) {
        System.out.println(Season.AUTUMN);
        System.out.println(Season.SUMMER);
    }
}

enum  Season {//类

    //定义了四个静态对象,使用了enum 来实现枚举类
    /*
    1. 使用关键字 enum 替代 class;
    2. public static final Season SPRING = new Season("春天", "温暖") 直接使用
      SPRING("春天", "温暖") 来代替,即常量名(实参列表);
    3. 如果有多个常量(对象), 使用 , 号间隔即可;
    4. 如果使用enum 来实现枚举,要求将定义常量对象的语句,写在第一行;
    5. 如果我们使用的是无参构造器,创建常量对象,则可以省略括号();
     */
    SPRING("春天", "温暖"), WINTER("冬天", "寒冷"), AUTUMN("秋天", "凉爽"),
    SUMMER("夏天", "炎热");// 调用了构造器
    
	// 下面定义对象的语句和上面的效果是一样的。
//    public static final Season SPRING = new Season("春天", "温暖");
//    public static final Season WINTER = new Season("冬天", "寒冷");
//    public static final Season AUTUMN = new Season("秋天", "凉爽");
//    public static final Season SUMMER = new Season("夏天", "炎热");

    private String name;
    private String desc;

    private Season() {//无参构造器

    }

    private Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

	// 打印对象的信息
    @Override
    public String toString() {
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

  • 说明:使用 enum 关键字后,Season 类中的对象变成了固定的对象,这样便能满足我们一开始提出的要求了。
  • 对比图如下:

四、枚举的注意事项和细节 

(1)当我们使用 enum 关键字开发一个枚举类时,默认会继承 Enum 类,而且是一个 final 类,不能再被其他类继承。
(2)传统的 public static final Season2 SPRING = new Season2(“春天”, “温暖”); 简化成 SPRING(“春天”, “温暖”), 这里必 须知道,它调用的是哪个构造器。
(3)如果使用无参构造器 创建 枚举对象时,其实参列表和小括号都可以省略。
(4)当有多个枚举对象时,使用(,)间隔,最后由一个分号结尾。
(5)定义类枚举对象的语句必须放在枚举类的第一句。

(6)使用 enum 关键字后,就不能再继承其它类了,因为 enum 类会隐式继承 Enum,而 Java 是单继承机制。

五、枚举类的常用方法

以下是枚举类型常用的方法以及它们的用途:

  • 代码演示:
public class EnumMethod {
    public static void main(String[] args) {

        //使用Season 枚举类,来演示各种方法
        Season autumn = Season.AUTUMN;

        //输出枚举对象的名字  AUTUMN
        System.out.println(autumn.name());
        
        //ordinal() 输出的是该枚举对象的次序/位置号,从0开始编号
        //AUTUMN 枚举对象是第三个,因此输出 2
        System.out.println(autumn.ordinal());

        // values方法,返回 Season2[]
        // 含有定义的所有枚举对象
        Season[] values = Season.values();
        
        System.out.println("===遍历取出枚举对象(增强for)====");
        for (Season season: values) {
            System.out.println(season);
        }

        //valueOf:将字符串转换成枚举对象,要求字符串必为已有的对象名,否则报异常
        //执行流程
        //1. 根据你输入的 "AUTUMN" 到 Season2的枚举对象去查找
        //2. 如果找到了,就返回,如果没有找到,就报错
        Season autumn1 = Season.valueOf("AUTUMN");
        System.out.println("autumn1=" + autumn1);
        System.out.println(autumn == autumn1);

        //compareTo:比较两个枚举常量,比较的就是位置号
 		// 就是把 Season.AUTUMN 枚举对象的位置号 和 Season.SUMMER枚举对象的位置号比较
        /*
        源码如下:

        public final int compareTo(E o) {
            return self.ordinal - other.ordinal;
        }
         */
        // Season.AUTUMN的编号[2] - Season.SUMMER的编号[3]
        System.out.println(Season.AUTUMN.compareTo(Season.SUMMER));

        // 最后补充了一个增强for
       int[] nums = {1, 2, 9};

       //普通的for循环
       System.out.println("=====普通的for=====");
       for (int i = 0; i < nums.length; i++) {
           System.out.println(nums[i]);
       }

       System.out.println("=====增强的for=====");

       //执行流程是 依次从nums数组中取出数据,赋给i, 如果取出完毕,则退出for
       for(int i : nums) {
           System.out.println("i=" + i);
       }
    }
}

六、枚举的优缺点

优点:

1.易读性和可维护性:枚举类型中的常量是有意义的、自描述的,使得代码更易读、易理解和易于维护。枚举常量具有唯一的名称,提供了更好的文档和注释。

2.类型安全:枚举类型在编译时进行静态类型检查,这意味着编译器可以确保只使用有效的枚举常量,提供了更高的类型安全性。

3.可限定的值集合:枚举类型定义了一个有限的值集合,限定了有效的取值范围。这可以帮助避免程序中出现无效或意外的取值。

4.避免魔法数值:使用枚举类型可以避免使用硬编码的魔法数值,提供了更好的代码可读性和可维护性。

5.增强的编译器支持:枚举类型在编译器层面提供了一些额外的支持,如自动添加常用方法(如values()、valueOf())、枚举常量的顺序等。

6.适用于状态和选项的表示:枚举类型非常适用于表示状态、选项和固定集合,如季节、颜色、星期几等。
 

缺点:

1.不适用于动态变化的数据:枚举类型是在编译时定义的,其常量集合是固定的。如果需要表示动态变化的数据集合,枚举类型可能不适合。

2.不适用于大型数据集合:如果需要表示大型的数据集合,枚举类型的常量定义可能会变得冗长和繁琐。

3.缺乏扩展性:枚举类型的常量是在编译时确定的,不支持动态添加或删除常量。因此,如果需要频繁地修改常量集合,可能会导致代码的改动和维护成本的增加。

4.不支持继承:枚举类型不支持继承,无法实现枚举类型之间的继承关系。
 

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

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

相关文章

P1028 [NOIP2001 普及组] 数的计算

时刻记住一句话&#xff1a;写递归&#xff0c;1画图&#xff0c;2大脑放空&#xff01;&#xff01;&#xff01; 意思是&#xff0c;自己写递归题目&#xff0c;先用样例给的数据画图&#xff0c;然后想一个超级简单的思路&#xff0c;直接套上去就可以了。 上题干&#xff…

Theta*: Any-Angle Path Planning on Grids 原文翻译

Theta*: Any-Angle Path Planning on Grids 文章目录 Theta*: Any-Angle Path Planning on Grids翻译摘要1.Introduction2. Path-Planning Problem and Notation3. Existing Terrain Discretizations4.Existing Path-Planning Algorithms4.1 A* on GridsA* with Post-Smoothed …

EFAK-v3.0.1版部署与使用

一、前言 EFAK&#xff08;(Eagle For Apache Kafka&#xff0c;以前称为Kafka Eagle&#xff09;用于在使用 Topic 的情况下监控 Kafka 集群。包含Offset 的产生、Lag的变化、Partition的分布、Owner、Topic的创建以及修改的时间等信息。 二、环境&安装包 官方下载连接E…

2023年【R1快开门式压力容器操作】考试资料及R1快开门式压力容器操作复审考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 R1快开门式压力容器操作考试资料参考答案及R1快开门式压力容器操作考试试题解析是安全生产模拟考试一点通题库老师及R1快开门式压力容器操作操作证已考过的学员汇总&#xff0c;相对有效帮助R1快开门式压力容器操作复…

运动鞋品牌识别

一、前期工作 1. 设置GPU from tensorflow import keras from tensorflow.keras import layers,models import os, PIL, pathlib import matplotlib.pyplot as plt import tensorflow as tfgpus tf.config.list_physical_devices("GPU")if gpus:gpu0 …

【Spring Boot 源码学习】自定义 Banner 信息打印

Spring Boot 源码学习系列 自定义 Banner 信息打印 引言往期内容主要内容1. ResourceBanner 打印1.1 添加默认的 banner.txt 资源文件1.2 指定任意路径的资源文件1.3 添加自定义的信息 2. ImageBanner 打印2.1 添加默认的图像资源文件2.2 指定任意路径的图像资源文件2.3 添加自…

网站监控是什么

在当今高度互联的世界中&#xff0c;网站已成为企业和个人成功的关键因素。无论是提供产品或服务&#xff0c;还是建立品牌形象&#xff0c;网站都是不可或缺的工具。然而&#xff0c;随着互联网用户对访问速度和用户体验的高要求&#xff0c;保持网站的稳定性和可用性变得至关…

旋转的数组

分享今天看到的一个题目&#xff0c;不同思路解法 题目 思路1&#xff1a;时间复杂度0(N*k&#xff09; void rotate(int *a,int N,int k)//N为数组元素个数 { while(k--) { int tema[N-1]; for(int rightN-2;right>0;right--) { a[right1]a[right]; } a[0]tem; …

Seata的部署和集成

文章目录 一、部署Seata的tc-server1.下载2.解压3.修改配置4.在nacos添加配置5.创建数据库表6.启动TC服务 二、微服务集成seata1.引入依赖2.修改配置文件 三、TC服务的高可用和异地容灾1.模拟异地容灾的TC集群2.将事务组映射配置到nacos3.微服务读取nacos配置 一、部署Seata的t…

静态web服务器开发之HTTP协议

文章目录 版权声明HTTP协议网址HTTPS补充&#xff1a;HTTP的无状态特性浏览器访问Web服务器流程HTTP协议请求报文HTTP GET请求报文分析POST请求方式要点总结 HTTP协议响应报文HTTP 响应报文分析HTTP 状态码要点总结 HTTP协议通信过程查看 版权声明 本博客的内容基于我个人学习…

矩阵论(Matrix)

​ 大纲 矩阵微积分&#xff1a;多元微积分的一种特殊表达&#xff0c;尤其是在矩阵空间上进行讨论的时候逆矩阵(inverse matrix)矩阵分解&#xff1a;特征分解&#xff08;Eigendecomposition&#xff09;&#xff0c;又称谱分解&#xff08;Spectral decomposition&#xf…

Spark SQL 时间格式处理

初始化Spark Sql package pbcp_2023.clear_dataimport org.apache.spark.SparkConf import org.apache.spark.sql.SparkSession import org.apache.spark.sql.functions.{current_date, current_timestamp}object twe_2 {def main(args: Array[String]): Unit {val con new …

优秀的时间追踪软件Timemator for Mac轻松管理时间!

在现代社会&#xff0c;时间管理成为了我们工作和生活中的一大挑战。如果你经常感到时间不够用&#xff0c;无法高效地完成任务&#xff0c;那么Timemator for Mac将成为你的得力助手。 Timemator for Mac是一款出色的时间追踪软件&#xff0c;它可以帮助你精确记录和管理你的…

Codeforces Round 786 (Div. 3) D. A-B-C Sort

D. A-B-C Sort 步骤 1 &#xff1a;当 a不为空时&#xff0c;从 a中取出最后一个元素&#xff0c;并将其移动到数组 b的中间。如果 b 当前长度为奇数&#xff0c;则可以选择&#xff1a;将 a 中的元素放到 b 中间元素的左边或右边。结果&#xff0c; a 变空&#xff0c; b 由 n…

【2023.11.24】Mybatis基本连接语法学习➹

基本配置 1.如果使用Maven管理项目&#xff0c;需要在pom.xml中配置依赖。 2.安装Mybatis-3.5.7.jar包 3.进行XML配置&#xff1a;这里将文件命名为mybatis-config.xml 配置数据库连接XML文件 <?xml version"1.0" encoding"UTF-8" ?> <!DO…

数据结构-归并排序+计数排序

1.归并排序 基本思想&#xff1a; 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到完全有序的序列&#xff1b;即先使每个子序列有序&#xff0c;再使子序列段间有序。若将两个有序表合并成一个…

Relabel与Metic Relabel

Prometheus支持多种方式的自动发现目标&#xff08;targets&#xff09;&#xff0c;以下是一些常见的自动发现方式&#xff1a; 静态配置&#xff1a;您可以在Prometheus配置文件中直接列出要监测的目标。这种方式适用于目标相对稳定的情况下&#xff0c;例如固定的服务器或设…

【多线程】Thread类的使用

目录 1.概述 2.Thread的常见构造方法 3.Thread的几个常见属性 4.启动一个线程-start() 5.中断一个线程 5.1通过共享的标记来进行沟通 5.2 调用 interrupt() 方法来通知 6.等待一个进程 7.获取当前线程引用 8.线程的状态 8.1所有状态 8.2线程状态和转移的意义 1.概述 …

字节序

计算机硬件有两种储存数据的方式&#xff1a;大端字节序big endian 和 小端字节序 little endian。 数值0x2211使用两个字节储存&#xff1a;高位字节是0x22&#xff0c;低位字节是0x11。 大端字节序&#xff1a;低位放高地址&#xff0c;高位字节在低地址&#xff0c;地址空间…

JDBC编程方法及细节

JDBC&#xff08;Java Database Connectivity&#xff09;是Java编程语言用于连接和操作数据库的API&#xff08;Application Programming Interface&#xff09;。它为开发人员提供了一组Java类和接口&#xff0c;用于与各种关系型数据库进行通信。使用JDBC&#xff0c;开发人…