首页 > 编程语言 >Java枚举(Enum)类型原理探求

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

时间:2023-01-28 21:33:18浏览次数:58  
标签:反编译 SeasonEnum Java SPRING Enum 枚举 public


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关键字用来定义枚举类,在IDEA中创建枚举类的菜单如下:

同样定义一个季节的枚举类, 代码可以简洁如下:

package cn.osxm.jcodef.func.base;
public enum SeasonEnum {
SPRING, SUMMER, AUTUMN, WINTER
}

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

  • 枚举成员默认是final、public、static (所以可以使用SeasonEnum.SPRING方式调用枚举成员)
  • 每一个枚举类型成员都可以看作是枚举类的实例 (SeasonEnum.SPRING的类型也是SeasonEnum)

在JUnit使用测试如下:

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

Java 枚举类的特性

Java枚举类的特性有:

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

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

Java枚举类实现的原理探求

ava枚举类型的奥秘就在编译阶段,枚举类在编译后会生成了一个扩展java.lang.Enum的类。这个可以通过JDK自带的javap工具来反编译生成的.class文件。对上面的生成的SeasonEnum.class文件进行反编译,因为这个文件的包路径是cn\osxm\jcodef\func\base,所以在命令行使用如下命令:

javap -p cn\osxm\jcodef\func\base\SeasonEnum.class
  • -p参数的意思是反编译代码中包含私有的方法, p是private的意思。

从控制台输出的反编译后的源码可以看出:

  • 自定义的枚举类会自动继承java.lang.Enum类
  • 每个成员变量都会被转换为 private static final的枚举类型的实例
  • 自动添加private的构造函数 从反编译后的源码就不难理解Enum的特性了。

注意: 使用专门的Java反编译工具,比如JD GUI、luyten等对Eumn进行反编译的效果接近源码的效果,无法看到继承等特性,JD-GUI反编译的效果和源码时一致的,这也说明使用JD GUI来进行实际的反编译还是不错的。

标签:反编译,SeasonEnum,Java,SPRING,Enum,枚举,public
From: https://blog.51cto.com/u_8238263/6025162

相关文章

  • java面试技巧:Integer和int的那些事⼉
    最近在招聘⾯试的过程中,考察⼀些候选⼈的基础掌握能⼒中发现,还是有⼤多数⼲了有1~3年的开发者在基础这块⼉掌握的不够牢靠,没有去思考过为什么这样做,以及这样做的原因是什么?......
  • java四大引用详解!
    什么是java四大引用? 是JDK1.2版本开始引入,把对象的引用分为4个等级,我们平时学习的就是四种的第一级的强引用,说白了,就Objecto=newObject(),四个引用分别是强引用、软引......
  • Java程序员必看:Solr vip竞价排名
    功能介绍本文将使用solr完成vip等级排名,这里并不是简单的按照vip等级排序。而是在使用solr条件查询(不使用排序)的时候将符合条件并且具有vip等级的数据显示在前面,这个时候......
  • Java:Path及Paths使用
    Java8Windows10-- 主要内容:Windows下测试,组合文件路径、Path转File等。 准备:D盘;D盘下bootweb目录(springboot项目);D盘下test.txt文件;D盘下其它目录及......
  • Java两大工具库:Commons和Guava(2)
    您好,我是湘王,这是我的51CTO博客。值此新春佳节,我给您拜年啦~祝您在新的一年中所求皆所愿,所行皆坦途,展宏“兔”,有钱“兔”,多喜乐,常安宁!开发中有一类应用会出现的比较多,就是文......
  • Java两大工具库:Commons和Guava(2)
    您好,我是湘王,这是我的博客园。值此新春佳节,我给您拜年啦~祝您在新的一年中所求皆所愿,所行皆坦途,展宏“兔”,有钱“兔”,多喜乐,常安宁!   开发中有一类应用会出现的比较......
  • JavaGuide--基础篇
    包装类型的缓存机制了解么?Java基本数据类型的包装类型的大部分都用到了缓存机制来提升性能。Byte,Short,Integer,Long这4种包装类默认创建了数值[-128,127]的相应类......
  • IDE中自带的java springboot项目的密码加密和解密
    IDE里搜这个类org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI,跑类的main方法进行加密参数:input=你的明文密码password=固定你自己公司的某个固定值algorithm=PBEWi......
  • JavaScript写一个连连看的游戏
    天天看到别人玩连连看,表示没有认真玩过,不就把两个一样的图片连接在一起么,我自己写一个都可以呢。使用Javascript写了一个,托管到github,在线DEMO地址查看:​​打......
  • JAVA加解密之AES
      <!--AES加密--><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-ext-jdk16</artifactId><......