Java | 少年,你真懂枚举吗?

✍🏼作者:周棋洛,大三计算机学生。
♉星座:金牛座
🏠主页:我的个人网站
🌐关键:Java 枚举 enum

在这里插入图片描述

引言

最近有读柏拉图的《理想国》,我不禁思考,要做一个看似xx的人,还是要做一个真正xx的人 。思考后,我想做一个真正xx的人,虽然可能做不到,但有句话鼓励着我,虽不能至,心向往之。

Java5中添加了enum关键字,今天我们来巩固基础,学习Java枚举的相关知识。

在这里插入图片描述

灵魂发问?

学一个知识,我脑袋中不仅会有好多问号?比如:

什么是枚举?

枚举是一种数据类型,用于表示一组有限且固定常量集合。枚举类型可以帮助开发人员编写更加清晰、可读性更高的代码,而不需要依赖于魔法数值或者字符串。

什么是java枚举类?

在Java中,枚举通过关键字enum定义,因此Java中的枚举类型也被称为枚举类(Enum class)。枚举类是一种特殊的类,用于表示枚举类型。

枚举类中的每个枚举常量都是类的一个实例,并且这些实例在定义时就被确定了,不能在运行时修改。

枚举类可以有方法,构造函数和字段,因此可以像普通类一样进行操作,但是枚举常量通常是不可变的。

在Java中,枚举类通常用于替代常量集合或者表示状态机等场景,以提高代码的可读性和可维护性。枚举类的使用方式类似于普通类,但其语法更简洁明了,因此很多情况下都是一个不错的选择。

java底层如何处理枚举类?

枚举类在java中被编译为一个普通的类,但是编译器会自动为枚举类添加一些特殊的方法和属性,比如values()方法用于返回枚举常量数组,valueOf()方法用于将字符串转换为对应的枚举常量等。

枚举类为什么不允许new?

在Java中,枚举类型是一种特殊的类,它已经预先定义了一组有限的实例。编译器会自动添加一些特殊的处理,使得枚举常量在类加载时就被创建,并且在整个JVM中只存在一个实例。

枚举常量的创建是在类加载时就完成的,而且在加载枚举类时,编译器会生成相应数量的枚举实例,这些实例是在静态代码块中进行初始化的(我们会在后续的反编译详细研究)。因此,枚举类在加载时就已经创建了所有可能的实例,不需要使用new关键字来实例化。

另外,枚举类通常用于一组有限的常量集合,也就是我们不需要在运行时动态地创建新的实例。因此,禁用new关键字实例化可以确保枚举类型的单例性和稳定性。

在这里插入图片描述

枚举类构造器不允许用public,protected等修饰?

当你给枚举类构造器用public,protected修饰时会提示“此处不允许使用修饰符xxx”,它允许空修饰符或者private修饰符,虽所private修饰符会提示“修饰符 'private' 对于枚举构造函数是冗余的”,但不报错。

为什么private时,提示冗余呢?因为当你定义一个枚举类时,编译器会自动将枚举常量的构造器设为私有的,这是为了防止在类外部创建新的枚举实例。所以,私有构造器可以保证枚举类型的单例性和不变性。

枚举类构造器是私有的,怎么证明?

枚举类的构造器是私有(private)的,怎么证明呢?

枚举类HttpCodeEnum

在枚举类中定义两个构造器。

public enum HttpCodeEnum {
   
    SUCCESS("成功", 200);

    String msg;
    int code;

    HttpCodeEnum() {
   
	}

    HttpCodeEnum(String msg, int code) {
   
        this.msg = msg;
        this.code = code;
    }
}

其实可以通过反射在程序运行时,动态获取构造器的信息,代码如下:

// 获取枚举类的构造方法
Constructor<?>[] declaredConstructors = HttpCodeEnum.class.getDeclaredConstructors();

// 遍历构造方法
for (Constructor<?> constructor : declaredConstructors) {
   
    // 输出构造方法的修饰符和名称
    System.out.println("Constructor: " + constructor.getModifiers() + " " + constructor.getName());
}

执行上面代码,结果如下:

Constructor: 2 com.zhouql.domain.entity.HttpCodeEnum
Constructor: 2 com.zhouql.domain.entity.HttpCodeEnum

有些小伙伴可能对反射不太了解,没关系看一下getModifiers源码:

/**
 * Returns the Java language modifiers for the executable represented by this object.
 * 返回此对象表示的可执行文件的Java语言修饰符。
 */
@Override
public int getModifiers() {
   
    return modifiers;
}

该方法的返回值是int,和修饰符的映射如下:
0:可能代表没有任何修饰符修饰。
1:可能代表被 public 修饰符修饰。
2:可能代表被 private 修饰符修饰。

这就清楚了,这个类有两个构造器,都是私有(private)的。

反编译,研究透彻

遇事不决,反编译看看,创建一个空的枚举类,如下:

/**
 * Date: 2024/5/15 14:18
 * Author: 王子周棋洛
 * Description: This is a newly created class.
 */

public enum HttpCodeEnum {
   
	
}

反编译结果如下:

public final class 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王子周棋洛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值