Java枚举(Enum)类型原理探求

在这里插入图片描述

Enum枚举类型

Enum的全写是Enumeration,这个词的翻译是列举、逐条陈述、细目。在程序语言中,枚举类型是一种特殊的数据类型(常用的数据类型比如字符串、整型),这种数据类型的变量值限定在固定的范围, 比如季节只有春夏秋冬,月份是12个。

Java中的枚举

枚举前时代

在Java语言中, 枚举类型从JDK1.5才开始提供。在这之前使用接口静态常量来实现相关功能(也可以是类静态常量),以季节为例:在不使用枚举类之前,一般使用接口静态常量实现。比如:

public interface Season {
	public static final int SPRING = 1;
	public static final int SUMMER = 2;
	public static final int AUTUMN = 3;
	public static final int WINTER = 4;
}

使用JUnit使用测试如下:

@Test
public void noEnum() {
	int i = 1;
	Assert.assertTrue(Season.SPRING == i);
}

使用接口静态常量的方式比较难限定变量的范围,而且定义繁琐,功能也很有限,于是在Java 1.5 中定义了一个枚举类型:java.lang.Enum

Java枚举的定义

类似类(class)和接口(interface)的定义,Java提供enum关键字用来定义枚举类,同样定义一个季节的枚举类, 代码可以简洁如下:

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

在枚举类中直接列出常量,常量遵循全部大写的规则。在上面的枚举类示例代码中,SPRING,SUMMER,AUTUMN,WINTER 是Season的成员。

枚举成员默认是public、static 、final(所以可以使用Season.SPRING方式调用枚举成员)每一个枚举类型成员都可以看作是枚举类的实例 (Season.SPRING的类型也是Season),在JUnit使用测试如下:

@Test
public void enumBase() {
	Season season = Season.SPRING;
	Assert.assertTrue(season.equals(Season.SPRING));
}

Java 枚举类的特性

Java枚举类的特性有:

  • 枚举成员是public、static 和 final。
  • 枚举可以实现接口,但不能继承接口。
  • 枚举类是final的,所以不能继承。
  • 枚举类的构造方法是私有的。
  • 枚举成员是枚举类的实例。

但是从上面Season枚举类的定义来看,完全看不出这些特性,这些特性是怎么来的呢? 请看下面的原理探求。

Java枚举类实现的原理探求

java枚举类型的奥秘就在编译阶段,枚举类在编译后会生成了一个扩展java.lang.Enum的类。这个可以通过反编译工具反编译生成的.class文件。对上面的生成的Season.class文件进行反编译:

package com.qjwy.system.util;

public final class Season extends Enum {

	private Season(String s, int i) {
		super(s, i);
	}

	public static Season[] values() {
		Season aseason[];
		int i;
		Season aseason1[];
		System.arraycopy(aseason = ENUM$VALUES, 0, aseason1 = new Season[i = aseason.length], 0, i);
		return aseason1;
	}

	public static Season valueOf(String s) {
		return (Season) Enum.valueOf(util/Season, s);
	}

	public static final Season SPRING;
	public static final Season SUMMER;
	public static final Season AUTUMN;
	public static final Season WINTER;
	private static final Season ENUM$VALUES[];

	static {
		SPRING = new Season("SPRING", 0);
		SUMMER = new Season("SUMMER", 1);
		AUTUMN = new Season("AUTUMN", 2);
		WINTER = new Season("WINTER", 3);
		ENUM$VALUES = (new Season[] { SPRING, SUMMER, AUTUMN, WINTER });
	}
}

从反编译后的源码可以看出:

  • 自定义的枚举类会自动继承java.lang.Enum类
  • 每个成员变量都会被转换为 public static final的枚举类型的实例
  • 自动添加private的构造函数

从反编译后的源码就不难理解Enum的特性了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

摄尔修斯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值